Linux System Programming · advanced · ~14 min

The producer/consumer pattern

Coordinate threads with a bounded queue, a mutex, and condition variables.

Lesson

Producer/consumer is the canonical multi-threaded design: one (or many) producer threads enqueue items, one (or many) consumer threads dequeue them. The queue is the synchronisation point.

Building blocks:

  • A circular buffer (or linked list).
  • A mutex protecting the queue.
  • A condition variable cv_not_empty — consumers wait on this when the queue is empty; producers pthread_cond_signal it when they enqueue.
  • A condition variable cv_not_full — producers wait on this when the queue is full; consumers signal it when they dequeue.

Always wait on a cond var inside a while loop checking the predicate, not an if. Spurious wakeups are real — POSIX explicitly allows pthread_cond_wait to return without a signal.

Code examples

#include <pthread.h>

#define CAP 8
static int buf[CAP];
static int head = 0, tail = 0, count = 0;
static pthread_mutex_t m  = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t  ne = PTHREAD_COND_INITIALIZER;  /* not empty */
static pthread_cond_t  nf = PTHREAD_COND_INITIALIZER;  /* not full */

static void produce(int x) {
    pthread_mutex_lock(&m);
    while (count == CAP) pthread_cond_wait(&nf, &m);
    buf[tail] = x; tail = (tail + 1) % CAP; count++;
    pthread_cond_signal(&ne);
    pthread_mutex_unlock(&m);
}

static int consume(void) {
    pthread_mutex_lock(&m);
    while (count == 0) pthread_cond_wait(&ne, &m);
    int x = buf[head]; head = (head + 1) % CAP; count--;
    pthread_cond_signal(&nf);
    pthread_mutex_unlock(&m);
    return x;
}

Common mistakes

  • Using if instead of while around pthread_cond_wait. Spurious wakeups will then dequeue from an empty buffer.
  • Signalling the wrong cond var (signalling ne after consuming instead of nf).

Summary

Producer/consumer = bounded queue + mutex + two cond vars (not_empty, not_full). Always wait inside a while (predicate-false) loop.

Practice with these exercises