登录
首页 >  Golang >  Go问答

Golang 中的取消模式

来源:stackoverflow

时间:2024-04-17 15:39:35 458浏览 收藏

Golang小白一枚,正在不断学习积累知识,现将学习到的知识记录一下,也是将我的所得分享给大家!而今天这篇文章《Golang 中的取消模式》带大家来了解一下##content_title##,希望对大家的知识积累有所帮助,从而弥补自己的不足,助力实战开发!


问题内容

这里引用了 50 shades of go:陷阱、陷阱和常见错误:

您还可以使用特殊的取消通道来中断 工人。

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)。因此,我们可以收到以下结果最快的工作人员(“先胜模式”),然后取消所有其他工作人员的工作并节省资源。

另一方面,根据规范:

对于语句中的所有情况,receive 的通道操作数 操作以及发送的通道和右侧表达式 语句在输入时按源顺序仅计算一次 “选择”语句。

据我了解,这意味着我们不能 中断工人 ,因为在任何情况下,所有工人都会评估函数 replicas[i]query,然后选择 case <-done 并完成执行。

您能指出我推理中的错误吗?


解决方案


您的推理是正确的,网站上的措辞并不完全清楚。这个“构造”实现的是 goroutine 不会永远挂起,但一旦搜索完成,goroutine 将正确结束。那里没有再发生任何事情。

一般来说,你不能从外部中断任何 goroutine,goroutine 本身必须支持某种终止(例如关闭通道、context.Context 等)。参见cancel a blocking operation in Go

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

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

您可以在这个Go Playground example中验证这一点。

今天关于《Golang 中的取消模式》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>