简体   繁体   中英

Golang Stop Worker but wait for buffered channel to be empty

I am trying to create a worker who keeps reading from a buffered channel and a stop channel.

Since the select statement selects randomly if both channels are ready the stop channel gets executed. Is there any way to order the selects instead of random so that if my buffered channel returns a value execute that code.

Using un-buffered channel could solve this but is there any way by using buffered channel?

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

The posted code an be simplified to:

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

If you want the worker to continue working as long as there's more to do even though stop is triggered, then reorganize the select:

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

If you close the channel when empty, then all you need to do is range over the channel. Above code will work even if you do not close the channel.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM