Golang中为什么Context的Cancel会扩散而普通Channel不会
Golang中为什么Context的Cancel会扩散而普通Channel不会
为什么在下面的代码中,两个 goroutine 都能接收到 context 的取消信号,但无法同时接收到“普通通道”的信号?
通道是“点对点”的,因此随机只有一个 goroutine 会从 ch 通道接收数据。
但为什么两个 goroutine 总是能接收到 ctx.Done() 信号?
package main
import "sync"
import "fmt"
import "time"
import "context"
func main() {
var wg sync.WaitGroup
ch := make(chan struct{})
wg.Add(2)
ctx, cancel := context.WithCancel(context.Background())
go func() {
defer wg.Done()
fmt.Println("start goroutine 1")
for {
select {
case <- ch:
fmt.Println("got ch at goroutine 1")
case <- ctx.Done():
fmt.Println("got done goroutine 1")
return
}
}
}()
go func() {
defer wg.Done()
fmt.Println("start goroutine 2")
for {
select {
case <- ch:
fmt.Println("got ch at goroutine 2")
case <- ctx.Done():
fmt.Println("got done goroutine 2")
return
}
}
}()
time.Sleep(time.Second)
ch <- struct{}{}
time.Sleep(time.Second)
cancel()
fmt.Println("wait goroutines")
wg.Wait()
}
输出:
apmattil@penguin:~/src/chan$ go run chan.go
start goroutine 1
start goroutine 2
got ch at goroutine 1
wait goroutines
got done goroutine 1
got done goroutine 2
apmattil@penguin:~/src/chan$ go run chan.go
start goroutine 2
start goroutine 1
got ch at goroutine 2
wait goroutines
got done goroutine 1
got done goroutine 2
更多关于Golang中为什么Context的Cancel会扩散而普通Channel不会的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang中为什么Context的Cancel会扩散而普通Channel不会的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
我来回答我自己的问题。
ctx.Done() 接收操作之所以有效,是因为上下文通道被关闭了。
如果你编辑以下代码,就能看到这一点:
case _, ok := <-ctx.Done():
fmt.Printf("got done goroutine 1 %t\n", ok)
return

