[英]How to handle multiple go-routines closing the same channel?
I am having 2 go-routines reading from a single channel.我有 2 个从单个频道读取的 go-routines。 After 4 seconds, I cancel the context and terminate the select loop.
4 秒后,我取消上下文并终止 select 循环。 Before terminating the loop I call close on the channel, since there are 2 go-routines the close gets called twice and causes a panic because one of the go-routines would have already closed the channel.
在终止循环之前,我在通道上调用了 close,因为有 2 个 go-routine,close 被调用了两次并导致恐慌,因为其中一个 go-routine 已经关闭了通道。 Currently I am using a recover to recover from the panic, is there a better way of doing this?
目前我正在使用恢复从恐慌中恢复,有没有更好的方法来做到这一点?
package main
import (
"context"
"fmt"
"sync"
"time"
)
func numberGen(ctx context.Context, numChan chan int) {
num := 0
doneCh := ctx.Done()
defer func() {
if r := recover(); r != nil {
fmt.Println("recovered from ", r)
}
}()
for {
select {
case <-doneCh:
fmt.Println("done generating...")
close(numChan)
return
default:
num++
numChan <- num
}
}
}
func main() {
ctx, cancelFn := context.WithCancel(context.Background())
numChan := make(chan int)
var wg sync.WaitGroup
wg.Add(2)
go numberGen(ctx, numChan)
go numberGen(ctx, numChan)
go func(cfn context.CancelFunc) {
time.Sleep(10 * time.Millisecond)
cfn()
}(cancelFn)
for n := range numChan {
fmt.Println("received value ", n)
}
time.Sleep(2 * time.Second)
}
Close the channel after the goroutines are done sending values.在 goroutine 完成发送值后关闭通道。
var wg sync.WaitGroup
wg.Add(2)
go numberGen(ctx, numChan, &wg)
go numberGen(ctx, numChan, &wg)
go func() {
wg.Wait()
close(numChan)
}()
Update numberGen
to call Done()
on the wait group.更新
numberGen
以在等待组上调用Done()
。 Also, remove the call to close
.另外,删除对
close
的调用。
func numberGen(ctx context.Context, numChan chan int, wg *sync.WaitGroup) {
defer wg.Done()
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.