goroutine 从具有动态循环的 channel 读取 WaitGroup 在返回之前被重用

标签 go channel goroutine

我正在开发一个小型实用程序,它需要迭代动态范围内的项目(可以是 100 或 100000)并将项目放入 channel 中。从该 channel ,另一个函数读取项目并分别对每个项目进行一些处理。 我正在尝试使用 sync.WaitGroup 来确保我的实用程序不会在 channel 中的所有项目都被处理之前退出。由于我对 channel 和 WaitGroup 还很陌生,所以我遇到了错误 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()
}

这是我正在研究的主要思想(不是确切的代码,而是具有相同数量功能的完全相同的体系结构)。

如何确保该实用程序仅在 channel 中的所有项目都是进程时才退出。

感谢任何帮助。

最佳答案

我终于让它工作了。

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()
}

关于goroutine 从具有动态循环的 channel 读取 WaitGroup 在返回之前被重用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57077877/

相关文章:

go - 从传递给函数的结构中获取名称

go - 在 Golang 中绕过 http_proxy

go - 坚持 Go 并发

go - 如何通过遍历列表来创建多个 CRON 函数

go - 如何使用 channel 广播消息

go - 如何在golang程序中使用client-go列出k8s集群中的所有Pod?

Goroutine 在调用函数返回时终止

multithreading - 如何跨线程共享包含发送方和接收方字段的结构?

iOS录制音频错误

go - Go例程中的 channel 使用情况