登录
首页 >  Golang >  Go教程

Go 语言中,当 context 被取消后,`

时间:2024-11-27 12:27:52 240浏览 收藏

知识点掌握了,还需要不断练习才能熟练运用。下面golang学习网给大家带来一个Golang开发实战,手把手教大家学习《Go 语言中,当 context 被取消后,`》,在实现功能的过程中也带大家重新温习相关知识点,温故而知新,回头看看说不定又有不一样的感悟!

Go 语言中,当 context 被取消后,`

上下文取消后,<-ctx.done()未执行的原因

在 go 语言中,使用 context.context 包可以实现协程间通信和取消。当 context 被取消后,<-ctx.done() 会被唤醒并返回,但有时它可能不会被执行。

这是因为<-ctx.done()阻塞在读取ctx.done()通道上。如果在调用cancel()之前,ctx通道中的数据已经准备好,则<-ctx.done()将不会被唤醒。

导致该问题的一个示例

以下代码演示了该问题:

package main

import (
    "context"
    "fmt"
)

func gen(ctx context.context) <-chan interface{} {
    ch := make(chan interface{})
    go func() {
        n := 0
        for {
            select {
            case <-ctx.done():
                fmt.println("done")
            default:
                n += 1
                ch <- n
            }
        }

    }()
    return ch
}

func main() {
    ctx, cancel := context.withcancel(context.background())

    for n := range gen(ctx) {
        fmt.println(n)
        if n == 5 {
            break
        }
    }
    defer cancel()
}

在这种情况下,for循环将在读取到第六个元素之前一直运行。这意味着,当cancel()被调用时,第六个元素已经准备好了。因此,<-ctx.done()不会被唤醒。

解决方法

可以通过关闭通道来解决此问题。当上下文被取消时,关闭通道将导致<-ctx.done()被唤醒。

以下代码显示了改进后的示例:

package main

import (
    "context"
    "fmt"
)

func gen(ctx context.Context) <-chan interface{} {
    ch := make(chan interface{})
    go func() {
        n := 0
        for {
            select {
            case <-ctx.Done():
                fmt.Println("done")
                close(ch) // 关闭通道,range结束
                return
            default:
                n += 1
                ch <- n
            }
        }

    }()
    return ch
}

func main() {
    ctx, cancel := context.WithCancel(context.Background())

    for n := range gen(ctx) {
        fmt.Println(n)
        if n == 5 {
            cancel()
            // break不能break,否则没有从ch中读取,就会一直阻塞在ch<-n
        }
    }
}

这样,无论第六个元素是否已经准备好,<-ctx.done()都将被唤醒,并关闭通道。

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

相关阅读
更多>
最新阅读
更多>
课程推荐
更多>