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

上下文 ctx.完成未执行,即使上下文已传递给 golang 中的函数

上下文 ctx.完成未执行,即使上下文已传递给 golang 中的函数

Go
慕村225694 2022-08-30 22:01:04
我只是不明白为什么是ctx。Done() 没有被执行,即使我正在传递上下文并从主调用取消?我在这里做错了什么?var c = make(chan string)func A(ctx context.Context) { for {    select {    case <-ctx.Done():        fmt.Println("killing AAAA")        return // kill A at least    default:        fmt.Println("in A1.. .. again")        c <- "yesss"    } }}//func B(ctx context.Context) {func main() {    ctx, cancel := context.WithCancel(context.Background())    fmt.Println("BEFORE Number of active goroutines ", runtime.NumGoroutine())    go A(ctx)    time.Sleep(2 * time.Second)    valueReceived := <-c    cancel()    fmt.Println("AFTER Number of active goroutines ", runtime.NumGoroutine())}
查看完整描述

1 回答

?
至尊宝的传说

TA贡献1789条经验 获得超10个赞

goroutine 执行默认分支两次,并在发送到 时阻止。不执行该案例,因为 goroutine 卡在默认分支中。c<-ctx.Done()


通过从选择事例而不是分支语句发送来解决此问题。


func A(ctx context.Context) {

    for {

        select {

        case <-ctx.Done():

            fmt.Println("killing AAAA")

            return // kill A at least

        case c <- "yesss":

            fmt.Println("in A1.. .. again")

        }

    }

}

您可能看不到单独具有此更改的,因为程序可以在 goroutine 运行完成之前退出。killing AAAA


等待 goroutine 完成以查看消息:


var wg sync.WaitGroup


func A(ctx context.Context) {

    defer wg.Done()

    for {

        select {

        case <-ctx.Done():

            fmt.Println("killing AAAA")

            return // kill A at least

        case c <- "yesss":

            fmt.Println("in A1.. .. again")

        }

    }

}


...


wg.Add(1)

go A(ctx)

time.Sleep(2 * time.Second)

valueReceived := <-c

cancel()

wg.Wait()


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

添加回答

举报

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