gpt4 book ai didi

go - gorouines 是否忽略 channel 的缓冲区大小

转载 作者:IT王子 更新时间:2023-10-29 01:18:49 25 4
gpt4 key购买 nike

环境:OS X 10.8,Go 1.0.2

我创建了一个缓冲区大小为 2 的 channel ,然后如果我将 channel 写入 3 次,它会抛出错误:

throw: all goroutines are asleep - deadlock!

当然是对的。

但是 如果我在 goroutine 中写 channel 四次或更多次,它工作正常,为什么? channel 的容量是 2,为什么 goroutines 忽略它或者忘记容量设置?我注释了读取 channel 代码,所以没有人会读取 channel 并节省容量。我还使用 time.Sleep 来等待所有 goroutines 完成他们的工作。

请查看以下代码: 包主

//import "fmt"

func main() {
c := make(chan int, 2)
/*c <- 1
c <- 2
c <- 3*/
for i:=0; i<4; i++ {
go func(i int) {
c <- i
c <- 9
c <- 9
c <- 9
}(i)
}
time.Sleep(2000 * time.Millisecond)

/*for i:=0; i<4*2; i++ {
fmt.Println(<-c)
}*/
}

有没有人可以打几下?谢谢,伙计们。

最佳答案

当 channel 被缓冲时,这意味着在缓冲区满之前它不会阻塞。一旦缓冲区已满,发送 goroutine 将在尝试向 channel 添加内容时阻塞。

这意味着这将阻止:

c := make(chan int)
c <- 1 // Block here, this is unbuffered !
println(<-c)

这将阻止:

c := make(chan int, 2)
c <- 1
c <- 2
c <- 3 // Block here, buffer is full !
println(<-c)

但是 goroutines 和 channel 的要点正是为了并发运行,所以这会起作用:

c := make(chan int)
go func() { c <- 1; }() // This will block in the spawned goroutine until...
println(<-c) // ... this line is reached in the main goroutine

类似地:

c := make(chan int, 2)
go func() { // `go ...` spawns a goroutine
c <- 1 // Buffer is not full, no block
c <- 2 // Buffer is not full, no block
c <- 3 // Buffer is full, spawned goroutine is blocking until...
}()
println(<-c) // ... this line is reached in the main goroutine

在您的示例中,您生成了四个不同的 goroutine,它们都将四个数字写入同一个缓冲 channel 。由于缓冲区是 2 < 16,它们最终会阻塞

但问题的症结在于Go的策略是wait only for the main goroutine :

Program execution begins by initializing the main package and then invoking the function main. When the function main returns, the program exits. It does not wait for other (non-main) goroutines to complete.

这意味着在您的第一个示例中,main goroutine 在到达行 c <- 3 时阻塞了.由于没有其他 goroutine 能够做任何可能解除阻塞的事情,运行时检测到程序已死锁并报告错误。

然而,在您的第二个示例中,spawned goroutines 阻塞,而 main 静静地继续直到执行结束,此时所有(阻塞的)spawned goroutines 都被默默地杀死,并且没有报错。

关于go - gorouines 是否忽略 channel 的缓冲区大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19834469/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com