Golang 频道睡着了
Golang channel is asleep
我是 golang 通道的新手,无法低估如果我指定通道缓冲区大小程序行为会发生变化的原因
package main
import (
"fmt"
)
func channels(in <-chan bool, out chan int) {
for {
select {
case _ = <-in:
fmt.Println("Close")
close(out)
return
default:
fmt.Println("Out")
out <- 1
break
}
}
}
func main() {
in := make(chan bool)
// in := make(chan bool, 1)
out := make(chan int)
go channels(in, out)
i := 0
// Loop:
for n := range out {
fmt.Println(n)
i += 1
if i > 10 {
fmt.Println("Send close")
in <- true // Here it is became asleep
return
}
}
fmt.Println("Done")
}
输出为:
Out
Out
1
1
Out
Out
1
1
Out
Out
1
1
Out
Out
1
1
Out
Out
1
1
Out
Out
1
Send close
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
/home/user/go-lessons/3/chan_4.go:39 +0x2c3
goroutine 19 [chan send]:
main.channels(0xc820072060, 0xc8200720c0)
/home/user/go-lessons/3/chan_4.go:16 +0x241
created by main.main
/home/user/go-lessons/3/chan_4.go:27 +0x97
exit status 2
如果我将 in := make(chan bool)
替换为 in := make(chan bool, 1)
它会正常工作。为什么会这样?
这是因为主 goroutine 卡住了写入 in
in <- true
并且另一个 goroutine 卡在写入 out
out <- 1
如果你写出一个 case
也应该可以工作:
for {
select {
case <-in:
fmt.Println("Close")
close(out)
return
case out <- 1:
fmt.Println("Out")
break
}
}
我是 golang 通道的新手,无法低估如果我指定通道缓冲区大小程序行为会发生变化的原因
package main
import (
"fmt"
)
func channels(in <-chan bool, out chan int) {
for {
select {
case _ = <-in:
fmt.Println("Close")
close(out)
return
default:
fmt.Println("Out")
out <- 1
break
}
}
}
func main() {
in := make(chan bool)
// in := make(chan bool, 1)
out := make(chan int)
go channels(in, out)
i := 0
// Loop:
for n := range out {
fmt.Println(n)
i += 1
if i > 10 {
fmt.Println("Send close")
in <- true // Here it is became asleep
return
}
}
fmt.Println("Done")
}
输出为:
Out
Out
1
1
Out
Out
1
1
Out
Out
1
1
Out
Out
1
1
Out
Out
1
1
Out
Out
1
Send close
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
/home/user/go-lessons/3/chan_4.go:39 +0x2c3
goroutine 19 [chan send]:
main.channels(0xc820072060, 0xc8200720c0)
/home/user/go-lessons/3/chan_4.go:16 +0x241
created by main.main
/home/user/go-lessons/3/chan_4.go:27 +0x97
exit status 2
如果我将 in := make(chan bool)
替换为 in := make(chan bool, 1)
它会正常工作。为什么会这样?
这是因为主 goroutine 卡住了写入 in
in <- true
并且另一个 goroutine 卡在写入 out
out <- 1
如果你写出一个 case
也应该可以工作:
for {
select {
case <-in:
fmt.Println("Close")
close(out)
return
case out <- 1:
fmt.Println("Out")
break
}
}