在 golang 中使用 context 包需要澄清

我正在学习 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,其结果在上下文被取消后将没有任何用处。请说清楚。


MMTTMM
浏览 82回答 1
1回答

慕田峪7331174

关键是你应该通知第一个 goroutine 某事发生了,它需要退出当前的例程。这就是selectgolang 提供的 io-multiplexing 所做的。第一个 goroutine 应该是这样的&nbsp;go func() {&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case <-time.After(time.Second * 5):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //...do some processing&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Send result on the channel or cancel if error&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Lets send result...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ch1 <- 11&nbsp; &nbsp; &nbsp; &nbsp; case <-ctx.Done():&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("ctx Cancelled again.")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }()
打开App,查看更多内容
随时随地看视频慕课网APP