How to create a producer and consumer in Go

Overview

The Producer-Consumer problem is an operating system problem. Here, the producer produces a message and passes it to the buffer. The consumer stores that message from the buffer and removes it from the buffer.

For better understanding, let’s explore an illustration.

The producer-consumer pattern

Explanation

In the illustration above, we have a producer that passes the data to a bufferThe consumer stores that data and removes it from the buffer.

Let's look at an example to learn its implementation in Go.

Example

package main
import (
"runtime/pprof"
"flag"
"log"
"fmt"
"runtime"
"os"
)
// Producer definition
type Producer struct {
text *chan int
done *chan bool
}
// produce start creating message and send it through channel
func (p *Producer) produce(max int) {
fmt.Println("Producer start message sending")
for i := 0; i < max; i++ {
fmt.Println("Message send by Producer ", i)
*p.text <- i
}
*p.done <- true // updates when message produced
fmt.Println("Producer message ends")
}
type Consumer struct {
text *chan int
}
// consume reads the text channel
func (c *Consumer) consume() {
fmt.Println("consumer start recieving message")
for {
message := <-*c.text
fmt.Println("Message recieved by consumer", message)
}
}
func main() {
// profile flags
cpuflag := flag.String("cpuflag", "", "update cpu profile to `file`")
memflag := flag.String("memflag", "", "update memory profile to the `file`")
// Get the max number from flag
max := flag.Int("n", 4, "Show message count")
flag.Parse()
// To create the maximum number of cores in the processor
runtime.GOMAXPROCS(runtime.NumCPU())
// CPU Profile creation
if *cpuflag != "" {
f, err := os.Create(*cpuflag)
if err != nil {
log.Fatal("Enable to create CPU profile: ", err)
}
if err := pprof.StartCPUProfile(f); err != nil {
log.Fatal("Enable to start CPU profile: ", err)
}
defer pprof.StopCPUProfile()
}
var text = make(chan int) // channel send its messages
var done = make(chan bool) // channel to intimate when production is done
//creating a Producer
//Start a goroutine for Produce.produce
producer := &Producer{text: &text, done: &done}
go producer.produce(*max)
//creating a Consumer
//Start a goroutine for Consumer.consume
consumer := &Consumer{text: &text}
go consumer.consume()
// End the program when the production is complete
<-done
// Memory profile creation
if *memflag != "" {
f, err := os.Create(*memflag)
if err != nil {
log.Fatal("Enable to create memory id: ", err)
}
runtime.GC() // get update on status
if err := pprof.WriteHeapProfile(f); err != nil {
log.Fatal("Enable to write memory id: ", err)
}
f.Close()
}
}

Explanation

  • Lines 3–9: We import the runtime/pprof, flag, log, fmt, runtime, and os packages.
  • Lines 16–19: We create a channel of the int and bool types for the Producer to transfer data using the chan keyword.
  • Lines 22–30: We create a function, produce, to send messages to consumers. We terminate it on the *p.done <-true condition.
  • Lines 33–35: We create an int type channel for the Consumer to read the message.
  • Lines 38–44: We create a function named consume for the Consumer, which shows the received messages.
  • Lines 48–52: We create two flags:
    • cpuflag: This is to update the CPU profile to the file.
    • memflag: This is to update the memory profile.
  • Line 54: We use parse.flag to get the values from the flags.
  • Line 57: We use runtime.GOMAXPROCS(runtime.NumCPU()) to create the maximum cores from the processor.
  • Lines 60–69: We use the if condition to implement cpuflag and identify if any error occurs.
  • Lines 71–72: We declare the text and done variables to send a message and get an intimation on sending the message.
  • Lines 76–77: We create a variable, Producer, and call the Producer function.
  • Lines 81–82: We create a variable, Consumer, and call the Consumer function.
  • Line 85: We use <-done to end the program from the producer's side.
  • Lines 88–99: We use the if condition to implement memflag and identify if any error occurs.

Free Resources

Copyright ©2026 Educative, Inc. All rights reserved