为了账号安全,请及时绑定邮箱和手机立即绑定

长时间运行的 go 例程完成时发出信号

长时间运行的 go 例程完成时发出信号

Go
开满天机 2022-05-18 10:07:06
在这段代码中,我有一个循环,它将一直运行到经过一定的时间。在此期间,我将随机数量的数字发送到一个通道,以由运行时间更长的 go 例程处理。问题是 goroutines 仍然需要完成某种任务(在这个例子中只是休眠)。如何确保发送到numbers通道的所有项目都已完成运行并且messages已读取发送到通道的所有项目?当我运行代码时,我看到 66 个数字应该已经运行并被读取。但输出仅显示 66 个中的 6 个已运行然后读出。0s10ms20ms30ms40ms50ms60ms70ms80ms90msRan 3Ran 5Ran 1Ran 0100msRan 4Ran 2110msDONE 66package mainimport (    "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)}
查看完整描述

1 回答

?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

使用等待组。由于numbers代表传入的工作,当您向 发送内容时numbers,您可以在等待组中添加一个:


wg.Add(1)

numbers <- i

当您阅读消息时,将该工作标记为已完成:


func Read(messages chan string, wg *sync.WaitGroup) {

    for m := range messages {

        wg.Done()

        fmt.Println(m)

    }

}

并且,等待等待组在 main 中完成:


wg.Wait()

fmt.Println("DONE", n)

声明可以传递给 goroutine 的等待组:


wg:=sync.WaitGroup{}

go Read(messages,&wg)


查看完整回答
反对 回复 2022-05-18
  • 1 回答
  • 0 关注
  • 99 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信