为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 中的取消模式

Golang 中的取消模式

Go
潇潇雨雨 2023-06-01 09:59:17
这是来自50 Shades Of Go: Traps, Gotchas and Common mistakes 的引述:您还可以使用特殊的取消通道来打断工人。func First(query string, replicas ...Search) Result {      c := make(chan Result)    done := make(chan struct{})    defer close(done)    searchReplica := func(i int) {         select {        case c <- replicas[i](query):        case <- done:        }    }    for i := range replicas {        go searchReplica(i)    }    return <-c}据了解,这意味着我们使用通道done提前中断工作人员而不等待完全执行(在我们的案例中执行replicas[i](query)。因此,我们可以从最快的工作人员(&ldquo;First Wins Pattern&rdquo;)收到结果,然后取消所有其他工人的工作并节省资源。另一方面,根据规范:对于语句中的所有情况,接收操作的通道操作数以及发送语句的通道和右侧表达式在输入&ldquo;select&rdquo;语句时按源顺序恰好计算一次。据我了解,这意味着我们不能interrupt the workers,因为在任何情况下,所有工作人员都会评估功能replicas[i]query,然后才选择case <- done并完成他们的执行。能否请您指出我推理中的错误?
查看完整描述

1 回答

?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

您的推理是正确的,网站上的措辞并不完全清楚。这个“构造”实现的是 goroutines 不会永远挂起,但是一旦搜索完成,goroutines 就会正确结束。那里什么也没有发生。

通常,您不能从外部中断任何 goroutine,goroutine 本身必须支持某种终止(例如关闭通道context.Context等)。

所以是的,在您发布的示例中,将同时启动所有搜索,最快的搜索结果将在到达时返回,只要搜索完成,其余的 goroutine 将继续运行。

剩下的怎么办?其余的将被丢弃(case <- done将被选中,因为无缓冲的通道不能容纳任何元素,并且不会有其他人从该通道接收更多)。


查看完整回答
反对 回复 2023-06-01
  • 1 回答
  • 0 关注
  • 82 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信