我正在开发一个小型实用程序,它需要迭代动态范围内的项目(可以是 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/