登录
首页 >  Golang >  Go问答

如何处理关闭同一通道的多个 go 例程?

来源:stackoverflow

时间:2024-04-04 21:45:27 436浏览 收藏

最近发现不少小伙伴都对Golang很感兴趣,所以今天继续给大家介绍Golang相关的知识,本文《如何处理关闭同一通道的多个 go 例程?》主要内容涉及到等等知识点,希望能帮到你!当然如果阅读本文时存在不同想法,可以在评论中表达,但是请勿使用过激的措辞~

问题内容

我有 2 个 go 例程从单个通道读取数据。 4 秒后,我取消上下文并终止选择循环。在终止循环之前,我在通道上调用 close ,因为有 2 个 go 例程,所以 close 被调用两次并导致恐慌,因为其中一个 go 例程已经关闭了通道。目前我正在使用恢复来从恐慌中恢复,有更好的方法吗?

package main

import (
    "context"
    "fmt"
    "sync"
    "time"
)

func numberGen(ctx context.Context, numChan chan int) {
    num := 0
    doneCh := ctx.Done()
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("recovered from ", r)
        }
    }()
    for {
        select {
        case <-doneCh:
            fmt.Println("done generating...")
            close(numChan)
            return
        default:
            num++
            numChan <- num
        }
    }
}

func main() {
    ctx, cancelFn := context.WithCancel(context.Background())
    numChan := make(chan int)
    var wg sync.WaitGroup
    wg.Add(2)
    go numberGen(ctx, numChan)
    go numberGen(ctx, numChan)

    go func(cfn context.CancelFunc) {
        time.Sleep(10 * time.Millisecond)
        cfn()
    }(cancelFn)

    for n := range numChan {
        fmt.Println("received value ", n)
    }

    time.Sleep(2 * time.Second)
}

解决方案


goroutine 发送完值后关闭通道。

var wg sync.waitgroup
wg.add(2)
go numbergen(ctx, numchan, &wg)
go numbergen(ctx, numchan, &wg)

go func() {
    wg.wait()
    close(numchan)
}()

更新 numbergen 以在等待组上调用 done()。另外,删除对 close 的调用。

func numberGen(ctx context.Context, numChan chan int, wg *sync.WaitGroup) {
    defer wg.Done()
    ...

今天关于《如何处理关闭同一通道的多个 go 例程?》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>