Producer Consumer Problem

Abstract

This problem is a classical example of a multi-process synchronization problem. This problem describes two processes, producers and consumers, who share a common fixed-size buffer used as a queue.

Scope

This article explains the producer-consumer problem in detail.

Definition

In producer-consumer problems, the producer’s job is to generate a piece of data, put it into the buffer, and start again. At the same time, the consumer is consuming the data (i.e. removing it from the buffer) one piece at a time. This problem is to make sure that the producer won’t try to add data into the buffer if it is full and the consumer won’t try to remove the data if it is empty.

To allow producer and consumer processes to run concurrently, we must have an available buffer of items that can be filled by the producer and emptied by the consumer. This buffer will reside in a region of memory that is shared by the producer and consumer processes. A producer can produce one item while the consumer is consuming another item.

For example, A compiler can produce assembly code that is consumed by an assembler. The assembler may produce object modules that are consumed by the loader. 

The producer and consumer must be synchronized so that the consumer does not try to consume an item that has not yet been produced.

There are two types of buffer :

  1. Unbounded buffer: It has no limit on the size of the buffer. The consumer may have to wait for new items, but the producer can always procure new items. 
  2. Bounded buffer: It assumes a fixed buffer size. The consumer must wait if the buffer is empty and the producer must wait if the buffer is full.

In the case of a bounded buffer, the problem assumes that the pool consists of n no. of buffers in which each is capable of holding one item. To execute the bounded buffer problem, requires:

  1. Mutex semaphore, which provides mutual exclusion accesses to the buffer pool and is initialized to the value 1 i.e semaphore mutex = 1.
  2. The empty and full semaphores that count the number of empty and full buffers, which can be initialized as 
empty = n;
full = 0;

Now the structure for the producer process can be represented as :

do {
  produce an item into the pool
    -
    - - - - - - - -
    wait(empty);
  wait(mutex); -
  - - - - - - - -
  - - - - - - -
  Add next process to buffer
    -
    - - - - - - - - -
    signal(mutex);
  signal(full);
} while (1);

Now the structure for the consumer process can be represented as –

do {
  wait(full);
  wait(mutex); -
  - - - - - - - - -
  remove an item from buffer to consume
  signal(mutex);
  signal(empty); -
  - - - - - - -
  consume the item to next c
} while (1);

SUMMARY

In producer-consumer process problem, the producer process produces information that is caused by the consumer process. It uses shared memory.

Special thanks to Ami Jangid for contributing to this article on takeUforward. If you also wish to share your knowledge with the takeUforward fam, please check out this article