关于channel的goroutine的疑问
来源:11-1 channel

HelloMing86
2019-12-20
老师,你好!关于channel的基本用法,我有一个疑问,希望你能帮我解答。
下面是我的代码(我的go版本是1.13.4)
package main
func main() {
ch := make(chan string, 3) // 创建缓冲区为3 的 通道
ch <- "a" // 标注1 main goroutine 向 通道ch 发送 "a"
ch <- "b" // 标注2 main goroutine 向 通道ch 发送 "b"
ch <- "c" // 标注3 main goroutine 向 通道ch 发送 "c"
<- ch // 标注4 请问,接收 通道ch 数据 的是哪个goroutine
ch <- "d" // 标注5 main goroutine 向 通道ch 发送 "d"
}
假如main函数中注释/删除掉[标注4]行的代码,会报“ deadlock!”错误。这个我理解,因为超过了缓冲区大小。
但是,在标注3和标注5之间加入标注4的代码,就不会报错。
我的疑问是:
channel不是在不同的goroutine之间进行通信吗?
main goroutine 向 通道ch 发送 “a”、“b”、“c”、“d”
请问,接收(<- ch)的goroutine是哪个?
写回答
1回答
-
ccmouse
2019-12-25
这个问题关键在于:这些都是在同一个goroutine中,你的这个程序没有使用go关键字来开辟goroutine,所以至始至终只有一个goroutine。
没有立刻死掉是因为我们的这个ch带缓冲区,大小为3。所以送三个值进去还是可以的,第四个就送不进去,因为没有其它goroutine收。
那么在标注4这一行收了一个数据之后,缓冲区里只剩2个元素,所以后面标注5的d就能够送进去。
你可以试试把标注4和标注5对换以下,会发现它仍然会deadlock,因为ch<-"d"这句就会卡住,运行不到下面的<-ch
关于:channel不是在不同的goroutine之间进行通信吗?是的,它是用来在不同goroutine之间通信。但没有禁止在同一个goroutine里面通信。如我们这个例子,如果channel带上缓冲区,还是能够在同一个goroutine里收发的,不过这样做没有什么实际的作用。
00
相似问题