Сигнал о завершении длительных go процедур - PullRequest
0 голосов
/ 13 февраля 2020

В этом коде у меня есть al oop, который будет работать, пока не пройдет определенное время. В течение этого времени я посылаю случайное количество чисел в канал для обработки более длительной подпрограммой go. Проблема в том, что подпрограммам go все еще нужно завершить sh, выполняя какое-то задание (в этом примере это просто сон). Как убедиться, что все элементы, отправленные на канал numbers, выполнены и все элементы, отправленные на канал messages, прочитаны?

Когда я запускаю код, я вижу, что 66 цифр должны были быть запущены и прочитаны. Но вывод показывает только 6 из 66, которые были запущены и затем считаны.

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

Go Детская площадка

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

1 Ответ

1 голос
/ 13 февраля 2020

Используйте WaitGroup. Поскольку numbers представляет входящую работу, когда вы отправляете что-то на numbers, вы можете добавить ее в группу ожидания:

wg.Add(1)
numbers <- i

И, читая сообщения, пометьте эту работу как выполненную:

func Read(messages chan string, wg *sync.WaitGroup) {
    for m := range messages {
        wg.Done()
        fmt.Println(m)
    }
}

И, дождитесь завершения группы ожидания в основном:

wg.Wait()
fmt.Println("DONE", n)

Объявите свою группу ожидания, где вы можете перейти к функциям:

wg:=sync.WaitGroup{}
go Read(messages,&wg)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...