Broadcast wakes every goroutine currently waiting on a condition variable, or replicates every input message to each output channel in a channel pipeline. Both uses let one event reach multiple concurrent receivers; they differ in whether receivers are waiting on shared state or consuming copied messages. section 5.1.3 section 9.4
With sync.Cond, Broadcast differs from Signal: Signal resumes one arbitrary waiter, while Broadcast resumes all current waiters. Use it when a shared-state change can release a group, such as when the last player joins a game or a waitgroup count reaches zero. section 5.1.3 section 6.1.4
Release players when the game is full
Each player handler locks the condition mutex, decrements playersRemaining, and waits in a loop while players remain. The handler that reduces the count to zero calls Broadcast, allowing every waiting handler to resume and begin the game. The loop rechecks shared state after waking. section 5.1.3 section 5.1.1
A condition-variable broadcast is not stored. If no goroutine is suspended in Wait when Broadcast runs, no later waiter receives it. Coordinate waiting and state updates with the associated mutex; Wait atomically releases that mutex while suspending, then reacquires it when resumed. section 5.1.2 section 5.1.1
In a channel pipeline, broadcast solves a different problem from fan-out. Fan-out load-balances distinct messages across workers; broadcast makes a copy of each message available to every downstream computation. A generic utility can create n output channels, forward each input message to all of them, and close all outputs when input ends. section 9.2.5 section 9.4
Listing 9.14 Broadcasting to multiple output channels
package listing9_14 func Broadcast[K any](quit <-chan int, input <-chan K, n int) []chan K { outputs := CreateAll[K](n) #1 go func() { defer CloseAll(outputs...) #2 var msg K moreData := true for moreData{ select { case msg, moreData = <-input: #3 if moreData { #4 for _, output := range outputs { #4 output <- msg #4 } } case <-quit: return } } }() return outputs #5 } #1 Creates n output channels of type K (see the next listing for the implementation) #2 Once complete, closes all output channels (see the next listing for the implementation) #3 Reads the next message from the input channel #4 If the input channel hasn’t been closed, writes the message to each output channel #5 Returns the set of output channels
The implementation shows the forwarding loop: receive one input value, send it to every output, stop on quit, and close all outputs on completion. Because it completes every send before reading again, one slow consumer slows the entire broadcast. section 9.2.5
Send words to two analyses
A word-processing pipeline broadcasts extracted words to longestWords and frequentWords. Each analysis receives the same word stream, so one can produce long words while the other calculates the most frequent words. section 9.2.5
