zon*_*gyi 2 channel go capacity goroutine
环境:OS X 10.8,Go 1.0.2
我创建一个缓冲区大小为2的通道,然后如果我写通道三次,它将抛出错误:
扔:所有的goroutines都睡着了 - 僵局!
当然,这是正确的.
但是如果我在goroutines中写入通道四次或更多次,它工作正常,为什么?频道的容量是2,为什么goroutines会忽略或忽略容量设置?我评论了读取通道代码,因此没有人会读取通道并保存容量.我也用time.Sleep等待所有goroutines完成他们的工作.
请查看以下代码:package main
//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)
}*/
}
Run Code Online (Sandbox Code Playgroud)
有人会请点击一下吗?多谢你们.
当通道被缓冲时,这意味着它将不会阻塞,直到缓冲区已满.一旦缓冲区已满,发送goroutine将在尝试向通道添加内容时阻止.
这意味着这将阻止:
c := make(chan int)
c <- 1 // Block here, this is unbuffered !
println(<-c)
Run Code Online (Sandbox Code Playgroud)
这也将阻止:
c := make(chan int, 2)
c <- 1
c <- 2
c <- 3 // Block here, buffer is full !
println(<-c)
Run Code Online (Sandbox Code Playgroud)
但是,点够程和渠道的恰恰是同时运行的东西,所以这将工作:
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
Run Code Online (Sandbox Code Playgroud)
同样地:
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
Run Code Online (Sandbox Code Playgroud)
在您的示例中,您生成了四个不同的goroutine,它们都将四个数字写入同一个缓冲通道.由于缓冲区为2 <16,它们将最终阻塞
但问题的关键在于Go政策只是等待主要的goroutine:
程序执行从初始化主包然后调用main函数开始.当函数main返回时,程序退出.它不等待其他(非主要)goroutines完成.
这意味着在您的第一个示例中,主 goroutine在到达线时会阻塞c <- 3.由于没有其他goroutine能够做任何可能解除阻塞的东西,运行时检测到程序已死锁并报告错误.
然而,在你的第二个例子中,产生的 goroutines阻塞,而main继续静止直到它到达执行结束,此时所有(被阻止的)产生的goroutine被静默杀死,并且没有报告错误.
| 归档时间: |
|
| 查看次数: |
216 次 |
| 最近记录: |