为了账号安全,请及时绑定邮箱和手机立即绑定

戈朗通道缺少一些值

戈朗通道缺少一些值

Go
摇曳的蔷薇 2022-08-24 15:47:01
我有以下代码package mainimport (    "fmt"    "math/rand"    "time")func main() {    concurrent := 12    ch := make(chan int)    defer close(ch)    for i := 1; i <= concurrent; i++ {        go worker(i, ch)    }    for i := 1; i <= 21; i++ {        ch <- i    }}func worker(worker int, ch chan int) {    for requestId := range ch {        fmt.Printf("worker %d is requesting to %d...\n", worker, requestId)        time.Sleep(time.Duration(rand.Intn(3)) * time.Second)    }}该函数启动运行该函数的多个 goroutine,然后将一些值放入通道中,这些值由 worker 打印。我的问题是,有时通道中的最后一个值甚至更多值不是由工作人员打印的。mainworkerworker 10 is requesting to 10...worker 5 is requesting to 1...worker 5 is requesting to 13...worker 7 is requesting to 6...worker 2 is requesting to 2...worker 3 is requesting to 7...worker 3 is requesting to 14...worker 6 is requesting to 4...worker 11 is requesting to 9...worker 9 is requesting to 8...worker 9 is requesting to 15...worker 12 is requesting to 11...worker 8 is requesting to 12...worker 8 is requesting to 16...worker 4 is requesting to 5...worker 1 is requesting to 3...worker 11 is requesting to 17...我认为这是因为主要功能在打印最后一个值之前结束并“杀死”所有运行goroutine,因为最后所有值都始终被打印出来。func main() {    concurrent := 12    ch := make(chan int)    defer close(ch)    for i := 1; i <= concurrent; i++ {        go worker(i, ch)    }    for i := 1; i <= 21; i++ {        ch <- i    }    time.Sleep(3 * time.Second)}如何在不使用睡眠的情况下解决此问题,并且如果可能的话仅使用通道?
查看完整描述

1 回答

?
RISEBY

TA贡献1856条经验 获得超5个赞

因为主 goroutine 在最后一个循环之后立即退出,导致整个程序也退出,所以后台 goroutines 可能会也可能不会有机会运行,你必须提供一些同步方法来“等待”所有工作线程完成。for


用sync.WaitGroup


   func main() {


    concurrent := 12

    ch := make(chan int)


    var wg sync.WaitGroup

    for i := 1; i <= concurrent; i++ {

        wg.Add(1)

        go func(i int) {

            defer wg.Done()

            worker(i, ch)

        }(i) // You have to pass i as parameter

    }

    for i := 1; i <= 21; i++ {

        ch <- i

    }

    close(ch) // Close channel to tell all workers to stop


    wg.Wait() // Wait all workers to finish its work

   }


查看完整回答
反对 回复 2022-08-24
  • 1 回答
  • 0 关注
  • 102 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号