What is the neatest idiom for producer/consumer in Go?

后端 未结 5 2122
不知归路
不知归路 2021-02-01 23:42

What I would like to do is have a set of producer goroutines (of which some may or may not complete) and a consumer routine. The issue is with that caveat in parentheses - we do

5条回答
  •  渐次进展
    2021-02-02 00:33

    There are always lots of ways to solve these problems. Here's a solution using the simple synchronous channels that are fundamental in Go. No buffered channels, no closing channels, no WaitGroups.

    It's really not that far from your "mouthful" solution, and--sorry to disappoint--not that much smaller. It does put the consumer in it's own goroutine, so that the consumer can consume numbers as the producer produces them. It also makes the distinction that a production "try" can end in either success or failure. If production fails, the try is done immediately. If it succeeds, the try is not done until the number is consumed.

    package main
    
    import (
        "fmt"
        "math/rand"
    )
    
    func producer(c chan int, fail chan bool) {
        if success := rand.Float32() > 0.5; success {
            c <- rand.Int()
        } else {
            fail <- true
        }
    }
    
    func consumer(c chan int, success chan bool) {
        for {
            num := <-c
            fmt.Printf("Producer produced: %d\n", num)
            success <- true
        }
    }
    
    func main() {
        const nTries = 10
        c := make(chan int)
        done := make(chan bool)
        for i := 0; i < nTries; i++ {
            go producer(c, done)
        }
        go consumer(c, done)
    
        for i := 0; i < nTries; i++ {
            <-done
        }
        fmt.Println("All done.")
    }
    

提交回复
热议问题