我被困在一种奇怪的情况下,对频道的写操作永远不会发生。
package main
import (
"fmt"
"time"
)
func main() {
c := make(chan int)
s := make(chan bool)
k := make(chan bool)
fmt.Println("start")
go func() {
fmt.Println("routine 1")
s <- true
}()
go func() {
fmt.Println("routine 2")
for {
select {
case <-s :
for i := 0; i < 3; i++ {
fmt.Println("before")
c <- i
fmt.Println("after")
}
case <- k :
fmt.Println("k ready")
break
}
}
}()
go func() {
fmt.Println("routine 3")
for {
select {
case x := <- c :
fmt.Println("x=", x)
k <- true
fmt.Println("k done")
}
}
}()
time.Sleep(1000 * time.Millisecond)
}这是输出:
start
routine 1
routine 2
before
routine 3
x= 0
after
before我不知道为什么写入通道k块,但是日志语句fmt.Println("k ready")从未被打印出来。
以下是我的想法:
据我所知,它应该能够写到通道k,然后戈鲁廷的案例2应该执行并打印"k就绪“。
有人能解释我为什么要写信给被封锁的频道吗?作为一个修复,我知道我可以增加通道c的缓冲区大小,所有的东西都会被打印出来,但是我不想修复这个问题,相反,我想了解这个场景。
一个很好的博客来理解上面的情况。
发布于 2017-01-21 17:21:40
你陷入僵局了。
s,然后退出s读取,并写入cc读取,然后写到k,这是因为没有从k读取的东西,因为在上面的k写中,k2被阻塞了。c,该块作为goroutine 3仍然试图写入k,因此没有从c读取。与您所说的相反,您没有1的缓冲区大小,缓冲区大小为零(即一个未缓冲的通道),所以写将阻塞,直到读取。这可能是你误解的根源。根据语言规范
可以使用内置函数
make创建一个新的初始化通道值,该函数以通道类型和可选容量作为参数: 制造(chan int,100) 容量(以元素数计)设置通道中缓冲区的大小。如果容量为零或缺失,则信道未缓冲,只有当发送方和接收方都准备就绪时,通信才能成功。否则,如果缓冲区不满(发送)或非空(接收),则信道被缓冲,通信成功而不阻塞。一个零频道从来没有准备好进行交流。
https://stackoverflow.com/questions/41782133
复制相似问题