r1笔记day27 goroutine and channel

Harmony ·
更新时间:2024-05-19
· 929 次阅读

一个简单的例子:

package main
import (
	"fmt"
	"time"
)
func test() {
	var i int
	for {
		fmt.Println(i)
		time.Sleep(time.Second)
		i++
	}
}
func main() {
	go test()
	for {
	}
}

例子2:

package main
import (
	"fmt"
	"sync"
	"time"
)
//阶乘结果存储map,key-value的方式存,并定义一个锁,避免资源竞争
var (
	m    = make(map[int]uint64)
	lock sync.Mutex
)
//任务编号
type task struct {
	n int
}
//计算阶乘任务
func calc(t *task) { //接受结构体的指针
	var sum uint64
	sum = 1
	for i := 1; i < t.n; i++ { //i 从1 开始递增,因为乘以0 等于0
		sum *= uint64(i)
	}
	lock.Lock()
	m[t.n] = uint64(sum) //要加锁,否则fatal error: concurrent map writes
	lock.Unlock()
}
func main() {
	//批量调用go routin
	for i := 0; i < 10; i++ {
		t := &task{n: i} //传地址
		go calc(t)
	}
	time.Sleep(10 * time.Second)
	lock.Lock()
	for k, v := range m {
		fmt.Printf("%d! =%v\n", k, v)
	}
	lock.Unlock()
}

运行结果:build时候注意添加 -race参数,查看是否存在竞争什么的。

PS F:\go> go build -race  F:\go\src\go_dev\day8\example\example03\main\main.go
PS F:\go> .\main.exe
0! =1
2! =1
4! =6
5! =24
7! =720
8! =5040
9! =40320
1! =1
3! =2
6! =120
PS F:\go>

channel的声明:

var 变量名 chan 类型

var test chan int
var test chan string
var test chan map[string]sting
var test chan stu
var test chan *stu //定义指针,就放地址进去

下面是例子: 

package main
import "fmt"
type student struct {
	Name string
}
func main() {
	/*
		//基本类型的channel
		fmt.Println("intchan")
		var intChan chan int
		intChan = make(chan int, 10)
		intChan <- 10
		//map类型的channel
		fmt.Println("mapchan")
		var mapChan chan map[string]string
		mapChan = make(chan map[string]string, 10)
		m := make(map[string]string, 16)
		m["stu1"] = "001"
		m["stu2"] = "002"
		mapChan <- m
		//自定义的channel
		fmt.Println("userchan")
		var stuChan chan student
		stu := student{Name: "stu1"}
		stuChan <- stu
		v := <-stuChan
		fmt.Println("userchan: ", v)
	*/
	//接口类型,啥都能存
	fmt.Println("intfchan")
	var intfChan chan interface{}
	intfChan = make(chan interface{}, 10)
	stu1 := student{Name: "stu2"}
	fmt.Println("intfchan<- ")
	intfChan <- &stu1
	//读interface的chan
	var rintf interface{}
	rintf = <-intfChan
	//类型转换
	var stu2 *student //存的是指针
	stu2, ok := rintf.(*student)
	if !ok {
		fmt.Println("can not convert")
		return
	}
	fmt.Println(stu2)
}

其中有个地方会阻塞了,还没解决,后面再来处理:

func main() {
	//自定义的channel
	fmt.Println("userchan")
	var stuChan chan student
	stu := student{Name: "stu1"}
	fmt.Println("userchan<- ")
	stuChan <- stu
	fmt.Println("<-userchan")
	v := <-stuChan
	fmt.Println("userchan: ", v)
}

output: 在 stuChan <- stu这里卡住了

PS F:\go> .\main.exe
userchan
userchan<-

后面继续学习,今天点到为止~


作者:XieHZ同学



goroutine AND

需要 登录 后方可回复, 如果你还没有账号请 注册新账号