我有两个goroutine:主worker
和一个helper
,它会为一些帮助而旋转。helper
可能会遇到错误,所以我使用一个通道将错误从helper
传递到worker
。
func helper(c chan <- error) (){
//do some work
c <- err // send errors/nil on c
}
下面是helper()
的调用方式:
func worker() error {
//do some work
c := make(chan error, 1)
go helper(c)
err := <- c
return err
}
问题:
- 语句
err := <- c
阻塞了worker
吗?我不这么认为,因为通道是缓冲的。 - 如果它是阻塞的,我如何使它成为非阻塞的?我的要求是让
worker
和它的调用者继续剩下的工作,而不需要等待通道上出现值。
谢谢。
4条答案
按热度按时间xtfmy6hx1#
您可以轻松验证
问:语句err:=〈- c会阻塞worker吗?我不这么认为,因为通道是缓冲的。
A:
err := <- c
会阻塞worker。问:如果它是阻塞的,我如何使它成为非阻塞的?我的要求是让worker和它的调用者继续剩下的工作,而不等待值出现在通道上。
**A:**如果不想阻塞,就把
err := <-c
去掉,如果最后需要err,就把err := <-c
移到最后。你不能不阻塞地读通道,如果你不阻塞地读通道,就不能再执行这段代码,除非你的代码在循环中。
你见过errgroup或waitgroup吗?
它使用原子,取消上下文和同步。一次实现这一点。
https://github.com/golang/sync/blob/master/errgroup/errgroup.go
https://github.com/golang/go/blob/master/src/sync/waitgroup.go
或者你可以直接使用它,运行func,然后在任何你想要的地方等待错误。
ac1kyiln2#
在你的代码中,剩下的工作与helper是否遇到错误无关。你可以在剩下的工作完成后简单地从通道接收。
kkbh8khc3#
以非阻塞方式从通道阅读的功能方式:
示例:https://go.dev/play/p/Njwyt32B4oT
注意:这个例子还有另一个方法CollectChanRemaining(),它读取通道中的所有缓冲元素。
smdncfj34#
我想你需要这个密码。
运行此代码