【问题标题】:Is there another way to make WaitGroup showed the process?是否有另一种方法可以让 WaitGroup 显示该过程?
【发布时间】:2022-01-04 02:18:45
【问题描述】:

这是我的片段代码来运行整个工作人员

for w := 1; w <= *totalworker; w++ {
        wg.Add(1)
        go worker(w, jobs, results, dir, &wg)
    }

这是我的工人

    defer wg.Done()
    for j := range jobs {
        filename := j[0][4] + ".csv"
        fmt.Printf("\nWorker %d starting a job\n", id)
        //results <- j //to show The result of jobs, unnecessary
        fmt.Printf("\nWorker %d Creating %s.csv\n", id, j[0][4])
        CreateFile(dir, &filename, j)
        fmt.Printf("\nWorker %d Finished creating %s.csv on %s\n", id, j[0][4], *dir)
        fmt.Printf("\nWorker %d finished a job\n", id)
    }
}

当我在没有 WaitGroup 的情况下运行时,它只会创建我需要的整个文件中的一小部分。但它显示了它的过程。它显示 worker1 做工作,worker2 做工作等等......所以直到程序结束它会显示每一个。

否则,使用 waitgroup 它会创建我需要的整个文件。但是,它完全合二为一,没有显示进程,显示当我用 WaitGroup 运行它时,它就像......等待整个过程在哪里xD,它刚刚以显示 Worker1 做工作,worker2 做工作等结束。 . 在程序结束时。

我可以用这个 Waitgroup 做些什么,让它显示它的每一个打印件?

【问题讨论】:

    标签: go concurrency worker waitgroup


    【解决方案1】:

    你需要创建一些通道来监听上一个通道完成了什么,这个我的例子我有20个例程,它们会同时处理一些逻辑,并按原始顺序返回:

    package channel
    
    import (
        "fmt"
        "sync"
        "time"
    )
    
    
    func Tests() {
    
        c := make(map[int]chan bool)
    
        var wg sync.WaitGroup
    
        // total go routine
        loop := 20
    
        // stop in step
        stop := 11
    
        for i := 1; i <= loop; i++ {
            // init channel
            c[i] = make(chan bool)
        }
    
        for i := 1; i <= loop; i++ {
            wg.Add(1)
            go func(c map[int]chan bool, i int) {
                defer wg.Done()
    
                // logic step
                fmt.Println("Process Logic step ", i)
    
                if i == 1 {
                    fmt.Println("Sending message first ", i)
                    c[i] <- true // send now notify to next step
                } else {
                    select {
                        case channel := <-c[i-1]:
                        defer close(c[i-1])
    
                        if channel == true {
                            // send now
                            fmt.Println("Sending message ", i)
                            // not sent
                            if i < loop { // fix deadlock when channel doesnt write
    
                                if i == stop && stop > 0 {
                                    c[i] <- false // stop in step i
                                } else {
                                    c[i] <- true // send now notify to next step
                                }
                            }
                        } else {
                            // not send
                            if i < loop { // fix deadlock when channel doesnt write
                                c[i] <- false
                            }
                        }
                    }
                }
            }(c, i)
        }
        wg.Wait()
        fmt.Println("go here ")
        //time.Sleep(3 * time.Second)go run
        fmt.Println("End")
    }
    

    【讨论】:

    • 那不是我的意思...media.giphy.com/media/6dzAwLPrP4LFvZFok6/giphy.gif看看这个...写的不同,但它在程序结束时同时打印。
    • 不要在循环内添加 wg.Add(),在运行例程之前使用 wg.Add(total)
    • 我对此不好。但是我仍然不明白为什么 println 没有一个一个显示,而是在程序结束时一次显示出来。
    猜你喜欢
    • 1970-01-01
    • 2014-12-13
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2019-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多