dongpang4470 2017-08-15 17:55
浏览 34
已采纳

执行例程有时会起作用,有时会给出关闭通道错误

I'm new to Go and I'm trying to learn about the concurrency patterns. When I run the following code, I sometimes get the expected results (a full array of numbers from 0 to 9999). Other times I just get a "That's it" message with the time displayed. And sometimes I just get a "Sending on closed channel" error. What could be going wrong here?

package main

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

func JobsDispatcher(in chan int, data []int){
    for _, value := range data{
        in<-value
    }
    close(in)
}

func Worker(in chan int, out chan int, wg *sync.WaitGroup){
    wg.Add(1)
    for{
        inMsg, ok := <-in
        if !ok{
            wg.Done()
            return
        }
        out <- inMsg
    }

}

func PrintInt(out chan int){
    for {
        outMsg, ok := <-out
        if !ok{
            fmt.Println("")
            fmt.Println("That's it")
            return
        }
        fmt.Println(outMsg)
    }
}

func ParallelPrint(data []int){
    var wg sync.WaitGroup

    in := make(chan int)
    out := make(chan int)

    parallelStartTime := time.Now()

    go JobsDispatcher(in, data)

    for i:=0;i<5;i++{
        go Worker(in,out,&wg)
    }


    go func(){
        wg.Wait()
        close(out)
    }()
    PrintInt(out)

    fmt.Println(time.Since(parallelStartTime))

}

func main(){
    data := make([]int,0)
    for i:=0;i<10000;i++{
        data = append(data, i)
    }

    ParallelPrint(data)
}
  • 写回答

2条回答 默认 最新

  • dsa88886666 2017-08-15 18:00
    关注

    This one is easy. This is why you never use WaitGroup's Add in a goroutine. Always call it before starting a goroutine.

    The problem is that you stack up a bunch of goroutine's and then call Wait immediately. Go does not promise to run your goroutines at any particular time, just like POSIX or Windows threads are not guaranteed.

    So, in this case, you gave the scheduler a bunch of goroutines to run in the future, but it decided to finish your code first. So it ran wg.Wait() and close(out) before ever doing wg.Add().

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 抖音咸鱼付款链接转码支付宝
  • ¥15 ubuntu22.04上安装ursim-3.15.8.106339遇到的问题
  • ¥15 求螺旋焊缝的图像处理
  • ¥15 blast算法(相关搜索:数据库)
  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?
  • ¥15 网络通信安全解决方案
  • ¥50 yalmip+Gurobi
  • ¥20 win10修改放大文本以及缩放与布局后蓝屏无法正常进入桌面
  • ¥15 itunes恢复数据最后一步发生错误
  • ¥15 关于#windows#的问题:2024年5月15日的win11更新后资源管理器没有地址栏了顶部的地址栏和文件搜索都消失了