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

在 golang 中使用 context 包需要澄清

在 golang 中使用 context 包需要澄清

Go
MMTTMM 2022-11-08 14:35:06
我正在学习 Go 语言。我了解取消上下文会在取消父操作或相关操作后中止操作。这应该节省正在进行的操作的资源,其结果将不会被使用。现在考虑下面的简单代码: package main  import (    "context"    "fmt"    "time" )  func main() {    var result int    ctx := context.Background()    ctx, cancel := context.WithCancel(ctx)    ch1 := make(chan int)     go func() {        time.Sleep(time.Second * 5)        //...do some processing        //Send result on the channel or cancel if error        //Lets send result...        ch1 <- 11    }()     go func() {        time.Sleep(time.Second * 2)        //...do some processing        //Send result on the channel or cancel if error        //Lets cancel...        cancel()    }()     select {    case result = <-ch1:        fmt.Println("Processing completed", result)    case <-ctx.Done():        fmt.Println("ctx Cancelled")    }     //Some other processing...    }ctx.Done() 满足 select 语句。我的问题是,即使在调用取消之后,第一个 goroutine 仍将继续,因为程序继续进行“其他处理......”因此,使用上下文的基本目的没有得到满足。我认为我的理解中遗漏了一些东西,或者有没有办法中止 goroutine,其结果在上下文被取消后将没有任何用处。请说清楚。
查看完整描述

1 回答

?
慕田峪7331174

TA贡献1828条经验 获得超13个赞

关键是你应该通知第一个 goroutine 某事发生了,它需要退出当前的例程。这就是selectgolang 提供的 io-multiplexing 所做的。第一个 goroutine 应该是这样的


 go func() {

        select {

        case <-time.After(time.Second * 5):

            //...do some processing

            //Send result on the channel or cancel if error

            //Lets send result...

            ch1 <- 11

        case <-ctx.Done():

            fmt.Println("ctx Cancelled again.")

            return

        }

    }()


查看完整回答
反对 回复 2022-11-08
  • 1 回答
  • 0 关注
  • 80 浏览
慕课专栏
更多

添加回答

举报

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