doujun1495 2019-07-17 14:09
浏览 107
已采纳

从具有动态循环的通道读取goroutine,获取waitgroup在返回上一个之前已被重用

I am working on a small utility which needs to iterate over a dynamic range of items (can be 100 or can be 100000) and put the items in a channel. From that channel another function reads the items and does some processing on each item individually. I am trying to use sync.WaitGroup to make sure that my utility does not exit before all the items in the channels are processed. As I am fairly new to channels and waitgroups, I am stuck with an error panic: sync: WaitGroup is reused before previous Wait has returned

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

package main

import (
    "fmt"
    "github.com/dchest/uniuri"
    "math/rand"
    "sync"
    "time"
)

var wg sync.WaitGroup
var count = 0

func printMe(msg string) {
    time.Sleep(1 * time.Second)
    fmt.Println(count, msg)
}

func makeMePrint(ch chan string) {
    for s := range ch {
        count++
        wg.Add(1)
        printMe(s)
        wg.Done()
    }

}

func writePrint(ch chan<- string) {
    fmt.Println("Starting to insert data in channel")
    for i := 1; i <= rand.Intn(30); i++ {
        s := uniuri.New()
        ch <- s
    }
    fmt.Println("We are done inserting all data in the channel")
    close(ch)
}

func main() {

    var ch = make(chan string)

    go writePrint(ch)
    go makeMePrint(ch)
    time.Sleep(1 * time.Second)
    wg.Wait()
}

This is the main idea of what I am working on (not the exact code but exactly the same architecture with same number of functions).

How can I make sure that the utility only exits only when all the items in the channel are processes.

Any help is appreciated.

  • 写回答

1条回答 默认 最新

  • dongtu1357 2019-07-18 07:53
    关注

    I finally got it to work.

    package main
    
    import (
        "fmt"
        "github.com/dchest/uniuri"
        "math/rand"
        "sync"
        "time"
    )
    
    var count = 0
    
    func printMe(msg string) {
        time.Sleep(1 * time.Second)
        fmt.Println(count, msg)
    }
    
    func makeMePrint(wg *sync.WaitGroup, ch chan string) {
        wg.Add(1)
        defer wg.Done()
    
        for s := range ch {
            count++
            printMe(s)
    
        }
    
    }
    
    func writePrint(wg *sync.WaitGroup, ch chan<- string) {
        wg.Add(1)
        defer wg.Done()
    
        fmt.Println("Starting to insert data in channel")
        for i := 1; i <= rand.Intn(30); i++ {
            s := uniuri.New()
            ch <- s
        }
        fmt.Println("We are done inserting all data in the channel")
        close(ch)
    }
    
    func main() {
        wg := &sync.WaitGroup{}
        var ch = make(chan string)
    
        go writePrint(wg, ch)
        go makeMePrint(wg, ch)
        time.Sleep(1 * time.Second)
        wg.Wait()
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂