[英]Signal when long running go routines are completed
In this code I have a loop that will run until a certain amount of time has passed.在这段代码中,我有一个循环,它会一直运行到经过一定的时间。 During this time I send a random amount of numbers to a channel to be processed by a longer running go routine.
在此期间,我将随机数量的数字发送到一个通道,以便由运行时间更长的 go 例程进行处理。 The problem is the go routines still need to finish doing some kind of task (just sleeping in this example).
问题是 go 例程仍然需要完成某种任务(在这个例子中只是睡觉)。 How do I make sure all of the items sent to the
numbers
channel are completed running and all of the items sent to the messages
channel are read?如何确保发送到
numbers
频道的所有项目都已完成运行并且所有发送到messages
频道的项目都已读取?
When I run the code I see 66 numbers should have run and been read.当我运行代码时,我看到 66 个数字应该已经运行并被读取。 But the output only shows 6 out of 66 were run and then read out.
但输出仅显示 66 个中的 6 个已运行然后读出。
0s
10ms
20ms
30ms
40ms
50ms
60ms
70ms
80ms
90ms
Ran 3
Ran 5
Ran 1
Ran 0
100ms
Ran 4
Ran 2
110ms
DONE 66
package main
import (
"fmt"
"math/rand"
"time"
)
func DoStuff(n int, messages chan string) {
time.Sleep(time.Duration(100) * time.Millisecond)
messages <- fmt.Sprintf("Ran %d", n)
}
func Read(messages chan string) {
for m := range messages {
fmt.Println(m)
}
}
func Run(numbers chan int, messages chan string) {
for n := range numbers {
go DoStuff(n, messages)
}
}
func main() {
var min = 1
var max = 10
var numbers = make(chan int)
var messages = make(chan string)
go Read(messages)
go Run(numbers, messages)
var n = 0
for start := time.Now(); ; {
elapsedTime := time.Since(start)
fmt.Println(elapsedTime)
if elapsedTime > time.Duration(100) * time.Millisecond {
break
}
var random = rand.Intn(max - min) + min
for i := 0; i < random; i++ {
n++
numbers <- i
}
time.Sleep(time.Duration(10) * time.Millisecond)
}
fmt.Println("DONE", n)
}
Use a WaitGroup.使用等待组。 Since
numbers
represent the incoming work, when you send something to numbers
, you can add one to the waitgroup:由于
numbers
代表传入的工作,当您向numbers
发送内容时,您可以向等待组添加一个:
wg.Add(1)
numbers <- i
And as you read from messages, mark that work as done:当您阅读消息时,将这项工作标记为已完成:
func Read(messages chan string, wg *sync.WaitGroup) {
for m := range messages {
wg.Done()
fmt.Println(m)
}
}
And, wait for the waitgroup to complete in main:并且,等待等待组在 main 中完成:
wg.Wait()
fmt.Println("DONE", n)
Declare your waitgroup where you can pass to goroutines:声明你的等待组,你可以在那里传递给 goroutines:
wg:=sync.WaitGroup{}
go Read(messages,&wg)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.