+ 收藏我们

网站模板

网站模板搜索
404模板 营销型模板 外贸网站模板 单页模板 双语模板 标签大全
电话:18630701785
首页 > 站长学院 > 如何处理关闭同一通道的多个 go 例程? >

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

时间:2024-04-06 14:39:56

最近发现不少小伙伴都对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()
    ...

有问题可以加入网站技术QQ群一起交流学习

本站会员学习、解决问题QQ群(691961965)

客服微信号:lpf010888

Title