请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

channel的收和发是不是一定要同时进行

我发现,channel如果单纯的只收,或者只发就不会有

fatal error: all goroutines are asleep - deadlock!

这样的错误,如果channel是有收有发的话,并且不是同时进行,就会有 deadlock 这样的错误,是不是channel的收和发必须是同时进行的,求老师和同学们解答

正在回答 回答被采纳积分+3

1回答

ccmouse 2020-05-27 21:48:02

这里“同时进行”不是你控制的,是go语言运行环境控制的。channel应该是有收有发才对,只有收或者只有发会死锁。

不过系统的死锁检测不是所有情况下都会报的。很多时候死锁了,系统并不会报出这个死锁的错误。

0 回复 有任何疑惑可以回复我~
  • 提问者 椰子树 #1
    那为什么
    func main()  {
    
    	go func() {
    		c := make(chan int)
    		c <- 2
    	}()
    	time.Sleep(time.Second)
    }
    这样就不会死锁,但是如果
    func main()  {
    
    	c := make(chan int)
    	c <- 2
    	time.Sleep(time.Second)
    }
    这样就会报死锁的错误,是不是如果只有收或者发的时候,放入协程中就可以避免死锁了
    回复 有任何疑惑可以回复我~ 2020-06-02 01:41:54
  • ccmouse 回复 提问者 椰子树 #2
    这个要具体分析,不是简单的说放不放协程。(首先要明白,死锁是一种现象,go运行时不一定会报死锁错误,但是表现为死锁)。死锁即是在go语言的channel下,仍然需要满足传统的死锁四个必要条件。(https://zhuanlan.zhihu.com/p/25677118)
    你的第一个例子的确不死锁,因为main协程中并没有任何等待。(sleep也可视为等待,不过是“可剥夺的等待”,不符合死锁的必要条件。实际现象也是程序在一秒后会正确退出。
    第二个例子的确死锁了。在c<-2,没有人会给这个c发送2,所以永远收不到这个2,如果系统不报错,那这个程序也将永远卡在这里不会退出。
    回复 有任何疑惑可以回复我~ 2020-06-03 16:18:37
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信