Multiple producer and multiple consumer

I have been writing code for multiple consumer and multiple producer pattern, but my code is giving a deadlock error.

I have created an anonymous function so that the “for…range” in consumer function doesn’t wait forever.

package main

import (
	"fmt"
	"sync"
	"sync/atomic"
)

func main() {
	noOfProducer := 10
	noOfConsumer := 10
	data := make(chan int64)
	var wg sync.WaitGroup

	// producer
	var ops int64
	for i := 0; i < noOfProducer; i++ {
		wg.Add(1)
		go func() {
			for c := 0; c < 100; c++ {
				atomic.AddInt64(&ops, 1)
				data <- atomic.LoadInt64(&ops)
			}
			wg.Done()
		}()
	}

	go func() {
		wg.Wait()
		close(data)
	}()

	// consumer
	for i := 0; i < noOfConsumer; i++ {
		wg.Add(1)
		go func(i int) {
			defer wg.Done()
			for data := range data {
				fmt.Printf("Value of i = %d Printed by consumer %d\n", data, i)
			}
		}(i)
	}
	wg.Wait()
}

Any help would be appreciated.

The consumer routine calls defer wg.Done() after the data channel closes. But the channel gets closed after wg.Wait() when all routines completed. See how these conditions block each other?

1 Like

Two different sync.WaitGroups should be used here, one for producers, and one for consumers. The wg.Wait() does not know if it should wait for consumers to finish, or for the producers to finish.

This is a working code that includes the discussed change.

1 Like

Thanks for the quick revert; the explanation solves the problem.