Basic Producer-Consumer Pattern with Buffered Channels
Owner: SnippetBot
Created: 2026-09-06 00:00:34
Size: 2.15 KB
Expires: Never
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package main
import (
"fmt"
"math/rand"
"time"
)
// producer sends numbers to a channel
func producer(id int, dataChan chan<- int) {
defer fmt.Printf("Producer %d: Exiting
", id)
for i := 0; i < 5; i++ {
num := rand.Intn(100)
fmt.Printf("Producer %d: Sending %d
", id, num)
dataChan <- num // Send to the channel
time.Sleep(time.Duration(rand.Intn(500)) * time.Millisecond)
}
}
// consumer receives numbers from a channel and processes them
func consumer(id int, dataChan <-chan int, done chan<- bool) {
defer fmt.Printf("Consumer %d: Exiting
", id)
for num := range dataChan { // Loop until the channel is closed
fmt.Printf("Consumer %d: Received %d, processing...
", id, num)
time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)
}
done <- true // Signal that this consumer is done
}
func main() {
rand.Seed(time.Now().UnixNano())
dataChan := make(chan int, 3) // Buffered channel to hold up to 3 items
doneChan := make(chan bool)
// Start producers
go producer(1, dataChan)
go producer(2, dataChan)
// Start consumers
numConsumers := 2
for i := 1; i <= numConsumers; i++ {
go consumer(i, dataChan, doneChan)
}
// Wait for all producers to finish (not explicitly shown here, but dataChan will close)
// A more robust solution would use a sync.WaitGroup for producers
fmt.Println("Main: Producers and consumers started. Waiting for all items to be processed.")
// Wait for all consumers to finish
// This waits for the data channel to be closed and all items consumed
go func() {
// In a real scenario, you'd close the dataChan after all producers are done.
// For this example, producers exit after 5 items, allowing the range loop to terminate.
// This isn't perfect, but demonstrates the pattern.
fmt.Println("Main: Simulating producers finishing and closing data channel...")
time.Sleep(6 * time.Second) // Give producers enough time to send
close(dataChan) // IMPORTANT: Close the channel to signal consumers no more data is coming
}()
for i := 0; i < numConsumers; i++ {
<-doneChan // Wait for each consumer to signal completion
}
fmt.Println("Main: All producers finished, all items processed, all consumers exited.")
}