猿问

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

在这段代码中,我有一个循环,它将一直运行到经过一定的时间。在此期间,我将随机数量的数字发送到一个通道,以由运行时间更长的 go 例程处理。问题是 goroutines 仍然需要完成某种任务(在这个例子中只是休眠)。如何确保发送到numbers通道的所有项目都已完成运行并且messages已读取发送到通道的所有项目?


当我运行代码时,我看到 66 个数字应该已经运行并被读取。但输出仅显示 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)

}



开满天机
浏览 100回答 1
1回答

素胚勾勒不出你

使用等待组。由于numbers代表传入的工作,当您向 发送内容时numbers,您可以在等待组中添加一个:wg.Add(1)numbers <- i当您阅读消息时,将该工作标记为已完成:func Read(messages chan string, wg *sync.WaitGroup) {&nbsp; &nbsp; for m := range messages {&nbsp; &nbsp; &nbsp; &nbsp; wg.Done()&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(m)&nbsp; &nbsp; }}并且,等待等待组在 main 中完成:wg.Wait()fmt.Println("DONE", n)声明可以传递给 goroutine 的等待组:wg:=sync.WaitGroup{}go Read(messages,&wg)
随时随地看视频慕课网APP

相关分类

Go
我要回答