从goroutine获取价值并取消另一个goroutine

Ron*_*ero 2 concurrency go goroutine

我有一个案例,我从两个不同的位置(ES和REDIS)读取数据,我需要从最快的源读取一个值,因此我发射2个goroutines,一个从ES获取数据,另一个获取来自REDIS.

一旦从其中一个goroutine中取出数据,必须完全取消另一个goroutine而不是浪费CPU.

简化:

func A(){
    go funcB(){

    }()

    go funcC(){

    }()

    data := <-channel // 
}
Run Code Online (Sandbox Code Playgroud)

现在一旦接收到数据,funcA或者funcB必须取消数据,无论他们做什么(我不再关心他们的输出,他们只是在浪费CPU)

什么是最有效的方法呢?可以只使用频道吗?

Jim*_*imB 6

背景下包提供的取消,暂停和期限上下文用于此目的.在这里你可以看到一个取消示例,我们等待较慢的goroutine打印已取消的消息:

ctx, cancel := context.WithCancel(context.Background())

// buffer the channel for extra results returned before cancelation
data := make(chan string, 2)

var wg sync.WaitGroup
wg.Add(1)
go func() {
    defer wg.Done()
    select {
    case <-time.After(100 * time.Millisecond):
        data <- "A complete"
    case <-ctx.Done():
        fmt.Println("A cancelled")
    }
}()

wg.Add(1)
go func() {
    defer wg.Done()
    select {
    case <-time.After(200 * time.Millisecond):
        data <- "B complete"
    case <-ctx.Done():
        fmt.Println("B cancelled")
    }
}()

resp := <-data
cancel()
fmt.Println(resp)
wg.Wait()
Run Code Online (Sandbox Code Playgroud)

https://play.golang.org/p/vAhksjKozW

  • @RonanDejhero:要扩展,说请求是基于http的,你可以采取http.Request,并使用[`WithContext`](https://golang.org/pkg/net/http/#Request.WithContext)自动取消上下文时取消http请求.如您所见,实际的取消代码对于客户端库和处理数据的代码路径将是唯一的. (2认同)