Sco*_*zer 5 concurrency deadlock go
我正在设置三个 goroutine 链,每个 goroutine 都有一个输入和一个输出通道。goroutine 将从输入通道读取数据,直到其关闭,增加值,然后将其发送到输出通道。但是,下面的程序因以下输出而陷入死锁:
goroutine 'one': 1
goroutine 'two': 2
goroutine 'three': 3
goroutine 'one': 10
goroutine 'two': 11
goroutine 'one': 100
fatal error: all goroutines are asleep - deadlock!
Run Code Online (Sandbox Code Playgroud)
代码:
package main
import (
"fmt"
)
func int_channel(id string, i chan int, o chan int) {
defer close(o)
for x := range i {
fmt.Printf("goroutine '%s': %d\n", id, x)
o <- x + 1
}
fmt.Println("done")
}
func main() {
c0 := make(chan int)
c1 := make(chan int)
c2 := make(chan int)
c3 := make(chan int)
go int_channel("one", c0, c1)
go int_channel("two", c1, c2)
go int_channel("three", c2, c3)
c0 <- 1
c0 <- 10
c0 <- 100
c0 <- 1000
c0 <- 10000
c0 <- 100000
close(c0)
fmt.Println("Sent all numbers to c0")
for x := range c3 {
fmt.Printf("out: %d\n", x)
}
}
Run Code Online (Sandbox Code Playgroud)
它挂起是因为从输出通道读取的循环永远不会到达,因此通道不会“清空”,一旦每个通道写入一个值,就无法取得任何进展,程序挂起。要修复它,请写入另一个 goroutine 中的输入,即
func main() {
c0 := make(chan int)
c1 := make(chan int)
c2 := make(chan int)
c3 := make(chan int)
go int_channel("one", c0, c1)
go int_channel("two", c1, c2)
go int_channel("three", c2, c3)
go func(){
c0 <- 1
c0 <- 10
c0 <- 100
c0 <- 1000
c0 <- 10000
c0 <- 100000
fmt.Println("Sent all numbers to c0")
close(c0)
}()
for x := range c3 {
fmt.Printf("out: %d\n", x)
}
}
Run Code Online (Sandbox Code Playgroud)
IOW,当c0 <- 1执行该行时,值流经所有三个通道并最终到达c3,但由于尚未到达读取器循环,因此它只是“坐在那里”。然后执行该行c0 <- 10,该值最终会出现c2,因为它无法写入c3- 之前的值仍然在那里,阻止写入。因此,当该行c0 <- 100执行时,所有通道都已满,无法取得进一步的进展。
| 归档时间: |
|
| 查看次数: |
3798 次 |
| 最近记录: |