Golang Остановите работника, но подождите, пока буферизованный канал не будет пуст - PullRequest
0 голосов
/ 03 апреля 2020

Я пытаюсь создать работника, который продолжает чтение из буферизованного канала и канала остановки.

Поскольку оператор выбора выбирает случайным образом, если оба канала готовы, выполняется остановка канала. Есть ли способ упорядочить выборки вместо случайных, чтобы, если мой буферизованный канал вернул значение, выполнил этот код.

Использование небуферизованного канала может решить эту проблему, но есть ли способ с использованием буферизованного канала?

https://play.golang.org/p/ZuMEkp6sJgv

Ответы [ 2 ]

2 голосов
/ 03 апреля 2020

Размещенный код может быть упрощен до:

var channel = make(chan int)
var wg sync.WaitGroup

var limit int = 50000

func main() {
    wg.Add(1)
    go worker()

    for i := 0; i < limit; i++ {
        channel <- i
    }
    close(channel)
    wg.Wait()
}

func worker() {
    defer wg.Done()
    for i := range channel {
        log.Println(i)
    }
}
0 голосов
/ 03 апреля 2020

Если вы хотите, чтобы работник продолжал работать до тех пор, пока есть еще что-то, даже если сработал стоп, то реорганизуйте выбор:

out:
select {
        case <-channel:
            doWork()
            for {
              select {
                 case <- channel:
                   doWork()
                 default:
                   break out
               }
            }
        case <-stop:
            log.Printf("In Stop %v", len(channel))
            return
        }
}

Если вы закрываете канал, когда он пуст, тогда все, что вам нужно сделать это диапазон по каналу. Выше код будет работать, даже если вы не закрываете канал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...