channel
这块我实际用的 真的特别少(一次都没有)..
所以自己学习再练习一下
有缓冲
有缓冲的,当写操作满了,读操作还没开始的话,也是会发生阻塞的
如果主程不结束,信道没写读完,也是会阻塞在那的!
c := make(chan int, 50)
go func() {
for i:=0;i<40;i++ {
fmt.Println("received---------", i)
x := <-c
fmt.Println("received", x)
}
fmt.Println("能走到这么")
}()
time.Sleep(2*time.Second)
for i:=0;i<10;i++ {
c <- i
fmt.Println("sending", i)
}
for {
}
如果写比读的多.. 会报错,说 所有线程都sleep
如果读比写多.. 读那块会阻塞! 没写完没有关系
如果读和写都比总数多.. 只有有读有写,就没事
如果读和写都比总数小.. 也没啥影响..
done := make(chan bool)
doSort := func(s []int) {
sort.Ints(s)
fmt.Println(s)
done <- true
}
s := []int{3,4,2,1,5,6,9,7,0,8}
i := len(s) >> 1
go doSort(s[:i])
go doSort(s[i:])
<-done
<-done
主程阻塞住,然后协程里写入数据,这时候主程才能继续走!
如果 用 range 去输出数据,写的有问题的话没有close的话,会报错,“fatal error: all goroutines are asleep - deadlock!” 所以正常range 最好是close!这样比较正常
无缓冲
比如:
ch := make(chan int) //创建一个无缓冲channel
fmt.Println(2342)
ch<-2
fmt.Println(234444444)
a := <-ch
fmt.Println(a)
无缓冲的时候,这种串行读写的话,都会发生阻塞,
2342
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
F:/workspaces/interview/ttest.go:31 +0xd5
Process finished with exit code 2
可以考虑这样写
ch := make(chan int) //创建一个无缓冲channel
fmt.Println(2342)
go func() {
ch<-2
}()
fmt.Println(234444444)
go func() {
a := <-ch
fmt.Println(a)
}()
放入两个协程里(一个也可以的),两个并发阻塞,一个开始写,一个准备读!
评论
使用 GitHub 账号即可参与加载较慢?可 直接前往 GitHub Discussions 查看与参与。