Skip to content

Instantly share code, notes, and snippets.

@nitishfy
Last active July 17, 2024 05:04
Show Gist options
  • Save nitishfy/e9f7afeed37c8efa5296a6de3b529b8b to your computer and use it in GitHub Desktop.
Save nitishfy/e9f7afeed37c8efa5296a6de3b529b8b to your computer and use it in GitHub Desktop.
Producer-Consumer Problem
// multiple producers, multiple consumers
package main
import (
"fmt"
"sync"
)
// producers sends the value to the channel
func producers(id int, ch chan<- int, wg *sync.WaitGroup) {
defer wg.Done()
for i:=1; i <= 100; i++ {
fmt.Printf("goroutine %d sent the value %d\n", id, i)
ch <- i
}
}
// consumers consumes the values
func consumers(id int, ch <-chan int, wg *sync.WaitGroup) {
defer wg.Done()
for val := range ch {
fmt.Printf("value received by goroutine %d: %d\n",id, val)
}
}
func main() {
ch := make(chan int)
var prowg sync.WaitGroup // separate waitgroup for producers
var conswg sync.WaitGroup // separate waitgroup for consumers
numProducers := 2
numConsumers := 3
for i:=1; i <= numProducers; i++ {
prowg.Add(1)
go producers(i, ch, &prowg)
}
for i:=1; i <= numConsumers; i++ {
conswg.Add(1)
go consumers(i, ch, &conswg)
}
go func () {
prowg.Wait()
close(ch)
}()
conswg.Wait()
}
// multiple producers, single consumer
package main
import (
"fmt"
"sync"
)
// producers sends the value to the channel
func producers(id int, ch chan<- int, wg *sync.WaitGroup) {
defer wg.Done()
for i:=1; i <= 100; i++ {
fmt.Printf("goroutine %d sent the value %d\n", id, i)
ch <- i
}
}
// consumers consumes the values
func consumers(id int, ch <-chan int, wg *sync.WaitGroup) {
defer wg.Done()
for val := range ch {
fmt.Printf("value received by goroutine %d: %d\n",id, val)
}
}
func main() {
ch := make(chan int)
var wg sync.WaitGroup
var prowg sync.WaitGroup // separate waitgroup for producers
numProducers := 2
for i:=1; i <= numProducers; i++ {
prowg.Add(1)
go producers(i, ch, &wg)
}
go func () {
prowg.Wait()
close(ch)
}()
wg.Add(1)
go consumers(i, ch, &wg)
wg.Wait()
}
//single producer, multiple consumers
package main
import (
"fmt"
"sync"
)
func producer(ch chan<- int, wg *sync.WaitGroup) {
defer wg.Done()
for i := 1; i <= 100; i++ {
ch <- i
fmt.Println("Produced:", i)
}
close(ch)
}
func consumer(id int, ch <-chan int, wg *sync.WaitGroup) {
defer wg.Done()
for num := range ch {
fmt.Printf("Consumer %d consumed: %d\n", id, num)
}
}
func main() {
ch := make(chan int)
var wg sync.WaitGroup
wg.Add(1)
go producer(ch, &wg)
numConsumers := 3
for i := 1; i <= numConsumers; i++ {
wg.Add(1)
go consumer(i, ch, &wg)
}
wg.Wait()
}
// single producer, single consumer
package main
import (
"fmt"
"sync"
)
func producer(ch chan<- int, wg *sync.WaitGroup) {
defer wg.Done()
for i := 1; i <= 100; i++ {
ch <- i
fmt.Printf("goroutine produce the value:%d\n", i)
}
close(ch)
}
func consumer(ch <-chan int, wg *sync.WaitGroup) {
defer wg.Done()
for val := range ch {
fmt.Printf("goroutine consumed the value:%d\n", val)
}
}
func main() {
ch := make(chan int)
var wg sync.WaitGroup
wg.Add(1)
go producer(ch, &wg)
wg.Add(1)
go consumer(ch, &wg)
wg.Wait()
}
@Shankjbs571
Copy link

nice

@ldemailly
Copy link

ldemailly commented Jul 10, 2024

replace

	go func ()  {
		prowg.Wait()
		close(ch)	
	}()
	
	conswg.Wait()

by simply

	prowg.Wait()
	close(ch)	
	conswg.Wait()

@eddycharly
Copy link

I would not pass the wait group to the producer/consumer (not its business).

func consumer(id int, ch <-chan int) {
	for num := range ch {
		fmt.Printf("Consumer %d consumed: %d\n", id, num)
	}
}

...

func main() {
	...

	numConsumers := 3
	for i := 1; i <= numConsumers; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			consumer(i, ch)
		}()
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment