我知道这是错的
func e6() {
c1 := make(chan struct{}, 1)
<-c1
go func() {
c1 <- struct{}{}
}()
}
这是对的
func e6() {
c1 := make(chan struct{}, 1)
go func() { //statement1
c1 <- struct{}{}
}()
<-c1 //statement2
}
由于我们不能在右边的例子中假设statement1和statement2的顺序,如果statement2在statement1之前执行会怎样,在这种情况下,右边的例子看起来就像是错误的例子,但为什么这样呢?谢谢你的帮助。
答案 0 :(得分:2)
实际上,这是在您生成goroutine之后会发生的事情:首先执行goroutine并填充通道,以便您可以立即从中读取(<-c1
)。或者首先执行read语句,但由于没有任何内容可以从该通道读取,因此它会等待直到可以读取某些内容(“It blocks”)。现在goroutine调度程序启动,注意到两个goroutine块中的一个并且它“最终”执行另一个goroutine,它填充通道并退出,使阻塞goroutine成为唯一剩余的,以便再次获得执行时间。但是现在通道被填充,可以读取,通道中的值被读取为空,原始goroutine继续,结束功能。
请注意,这有点简化了,你一定要阅读goroutines。
答案 1 :(得分:0)
这是错误的:
func e6() {
c1 := make(chan struct{}, 1)
<-c1
go func() {
c1 <- struct{}{}
}()
}
因为执行陷入僵局。通过在主函数线程中调用<-c1
,您将阻止来自开放通道的接收。接收将阻塞,直到它从c1
收到一些数据,但没有进程在其上发送任何数据。由于代码执行在到达c1
语句之前被阻止,因此假设在go
上发送的goroutine尚未启动。
在正确的实施中:
func e6() {
c1 := make(chan struct{}, 1)
go func() { //statement1
c1 <- struct{}{}
}()
<-c1 //statement2
}
首先运行哪个语句并不重要。如果statement1
首先运行,那么goroutine(在不同的线程中运行)会阻止c1
(c1 <- struct{}{}
)上的发送,因为statement2
尚未执行,而没有其他进程正在从c1
接收数据。这导致整个goroutine阻塞并让执行到statement2
将执行的主函数线程(请记住go
语句通常不会阻塞)。此时statement2
不会阻止,因为其他一些流程(statement1
)已准备好通过c1
发送数据。因此两个线程都继续完成。
对于statement2
首先执行的情况,可以进行类似的推理。