Sling Academy
Home/Golang/Implementing a Producer-Consumer Model in Go

Implementing a Producer-Consumer Model in Go

Last updated: November 27, 2024

Understanding the Producer-Consumer Model

The Producer-Consumer model is a design pattern used in concurrent programming, where two processes, the producer and the consumer, share a common buffer. The producer generates data and places it in the buffer, and the consumer retrieves the data from the buffer for processing. This model helps optimize resources by decoupling the processes that produce and consume data.

Setting Up Your Go Environment

Before we start coding, make sure you have Go installed on your system. Set up your workspace and create a directory for your project:

$ mkdir producer-consumer
$ cd producer-consumer

Implementing the Concurrent Model in Go

We'll write a simple Go program that demonstrates the producer-consumer model. In this example, the producer will generate random numbers, and the consumer will read these numbers and print them to the screen.

Step 1: Import Necessary Packages

package main

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

Step 2: Define the Functionality

Let's define some constants and create the buffer for communication using a channel.

const bufferSize = 10
const numberOfItems = 50

func main() {
    var wg sync.WaitGroup
    buffer := make(chan int, bufferSize)

    wg.Add(2)
    go producer(buffer, &wg)
    go consumer(buffer, &wg)

    wg.Wait()
}

Step 3: Create the Producer Function

The producer function generates random numbers and sends them to the buffer channel.

func producer(buffer chan<- int, wg *sync.WaitGroup) {
    defer wg.Done()
    rand.Seed(time.Now().UnixNano())
    for i := 0; i < numberOfItems; i++ {
        num := rand.Intn(100)
        buffer <- num
        fmt.Println("Produced:", num)
    }
    close(buffer)
}

Step 4: Create the Consumer Function

The consumer function reads from the buffer channel and processes the numbers (in this case, prints them).

func consumer(buffer <-chan int, wg *sync.WaitGroup) {
    defer wg.Done()
    for num := range buffer {
        fmt.Println("Consumed:", num)
    }
}

Conclusion

In this article, we implemented a basic producer-consumer pattern in Go using goroutines and channels. This pattern is crucial for efficiently managing concurrent tasks and can be customized for various use cases by simply modifying the producer and consumer logic.

Remember, Go's powerful concurrency model with channels and goroutines makes handling such design patterns much more straightforward compared to other programming languages.

Next Article: Concurrency in Go with Maps: Using `sync.Map`

Previous Article: Processing HTTP Requests Concurrently in Go Servers

Series: Concurrency and Synchronization in Go

Golang

Related Articles

You May Also Like

  • How to remove HTML tags in a string in Go
  • How to remove special characters in a string in Go
  • How to remove consecutive whitespace in a string in Go
  • How to count words and characters in a string in Go
  • Relative imports in Go: Tutorial & Examples
  • How to run Python code with Go
  • How to generate slug from title in Go
  • How to create an XML sitemap in Go
  • How to redirect in Go (301, 302, etc)
  • Using Go with MongoDB: CRUD example
  • Auto deploy Go apps with CI/ CD and GitHub Actions
  • Fixing Go error: method redeclared with different receiver type
  • Fixing Go error: copy argument must have slice type
  • Fixing Go error: attempted to use nil slice
  • Fixing Go error: assignment to constant variable
  • Fixing Go error: cannot compare X (type Y) with Z (type W)
  • Fixing Go error: method has pointer receiver, not called with pointer
  • Fixing Go error: assignment mismatch: X variables but Y values
  • Fixing Go error: array index must be non-negative integer constant