---
title: "Producer-consumer: semaphore and messages"
subject: "Operating System"
chapter: 3
key: "semester_6/operating_system:pc-semaphore-message-passing"
source: https://www.bctengineer.com/q/semester_6/operating_system/pc-semaphore-message-passing
site: BCT Engineering
---

# Producer-consumer: semaphore and messages

Operating System · Chapter 3: Process Communication and Synchronization

- Asked in: 2073 Magh, 2+2+6 marks
- Video: [Bounded Buffer Problem|Problems Of Synchronization part1| producer consumer problem using semaphore](https://www.youtube.com/watch?v=yw__NPExEH4) — Sudhakar Atchala
- Answer checked by Claude Opus 5.5 (high effort) on 2026-10-14
- Page: https://www.bctengineer.com/q/semester_6/operating_system/pc-semaphore-message-passing
- Whole chapter: https://www.bctengineer.com/md/semester_6/operating_system/chapter-3

## Question

Define race condition. What are the requirements of mutual exclusion? Solve the producer consumer problem using semaphore and message passing.

## Short answer

A race condition occurs when shared data is accessed concurrently and the outcome depends on the exact scheduling order. Mutual exclusion requires that no two processes be in their critical regions at once, no assumptions about speed, and bounded waiting. Producer-consumer with semaphores uses mutex, empty (init N) and full (init 0). With message passing, consumer sends N empty messages; producer receives an empty, fills it, and sends it back.

## Answer

#### Race condition

A **race condition** is a situation in which two or more processes read and write shared data, and the final result depends on the exact order in which they run (who "wins the race"). Example: two processes each do `count = count + 1` on a shared variable; if both read the old value before either writes, one update is lost.

#### Requirements of mutual exclusion

1. No two processes can be in their critical regions at the same time.
2. No assumptions about the speed or number of CPUs.
3. No process outside its critical region may block another process.
4. No process waits forever to enter (bounded waiting).

#### Producer-consumer using semaphores

(The shared buffer has N slots; `mutex = 1`, `empty = N`, `full = 0`.)

```c
#define N 100                 /* number of slots in the buffer */
typedef int semaphore;
semaphore mutex = 1;          /* controls access to the buffer */
semaphore empty = N;          /* counts empty slots */
semaphore full  = 0;          /* counts full slots */

void producer(void) {
    int item;
    while (TRUE) {
        item = produce_item();    /* make an item */
        down(&empty);             /* wait for an empty slot */
        down(&mutex);             /* enter critical region */
        insert_item(item);        /* put item in buffer */
        up(&mutex);               /* leave critical region */
        up(&full);                /* one more full slot */
    }
}

void consumer(void) {
    int item;
    while (TRUE) {
        down(&full);              /* wait for a full slot */
        down(&mutex);             /* enter critical region */
        item = remove_item();     /* take item from buffer */
        up(&mutex);               /* leave critical region */
        up(&empty);               /* one more empty slot */
        consume_item(item);       /* use the item */
    }
}
```

#### Producer-consumer using message passing

Processes communicate with the primitives `send(destination, &message)` and `receive(source, &message)`, so no shared memory is needed. The consumer starts by sending N empty messages to the producer; each empty message represents an empty slot. The producer receives an empty message (blocking if none), fills it with an item and sends it back. The consumer receives the full message, extracts the item, returns an empty message and consumes the item. The number of messages in the system is fixed at N, so the buffer cannot overflow and no semaphores are needed.

```c
#define N 100                        /* number of slots in the buffer */

void producer(void) {
    int item;
    message m;                       /* message buffer */
    while (TRUE) {
        item = produce_item();
        receive(consumer, &m);       /* wait for an empty message */
        build_message(&m, item);     /* construct a message with the item */
        send(consumer, &m);          /* send item to consumer */
    }
}

void consumer(void) {
    int item, i;
    message m;
    for (i = 0; i < N; i++)
        send(producer, &m);          /* send N empty messages */
    while (TRUE) {
        receive(producer, &m);       /* get a message with an item */
        item = extract_item(&m);     /* take the item out */
        send(producer, &m);          /* send back an empty reply */
        consume_item(item);
    }
}
```

Messages sent but not yet received are buffered by the OS. If the producer is faster, it blocks at `receive` until empty messages arrive; if the consumer is faster, it blocks at `receive` until full messages arrive. Message passing also works across machines (distributed systems), but it is slower than semaphores because of copying and communication.

## Check yourself

The answer's key points as multiple-choice questions, with the correct option and why.

1. Which best describes a race condition?
   A. A process runs faster than another
   B. The final result of shared-data access depends on exact execution order
   C. Two processes wait for each other forever
   D. A process never gets the CPU
   Answer: B. A race condition occurs when outcome depends on the order in which processes access shared data, e.g. lost updates to count. (Key point: Race condition)

2. In the semaphore solution, what is the role of 'full' initialised to 0?
   A. It protects the buffer
   B. It counts empty slots
   C. It records the number of consumers
   D. It counts filled slots and blocks the consumer when 0
   Answer: D. The consumer does down(full) and sleeps if no filled slot exists. (Key point: Semaphore roles)

3. In the message-passing solution, what does the consumer do first?
   A. Sends N empty messages to the producer
   B. Receives N full messages
   C. Initialises three semaphores
   D. Locks the buffer
   Answer: A. Each empty message represents an empty slot, so the consumer starts by sending N of them. (Key point: Message passing setup)

4. Why can the buffer not overflow in the message-passing solution?
   A. A semaphore guards it
   B. The producer checks a counter
   C. The total number of messages is fixed at N and the producer blocks at receive when none are empty
   D. The OS discards extra items
   Answer: C. Only N messages exist; with no empty message the producer blocks on receive. (Key point: Overflow prevention)

## Related in Operating System

- [Race condition; mutual exclusion requirements](https://www.bctengineer.com/question.md?key=semester_6%2Foperating_system%3Arace-mutual-exclusion-requirements) — Operating System, chapter 3
- [Producer-consumer using semaphore](https://www.bctengineer.com/question.md?key=semester_6%2Foperating_system%3Apc-semaphore-mutual-exclusion) — Operating System, chapter 3, asked 2×
- [Semaphore for mutual exclusion](https://www.bctengineer.com/question.md?key=semester_6%2Foperating_system%3Asemaphore-enforce-mutual-exclusion) — Operating System, chapter 3
- [TSL; producer-consumer using monitors](https://www.bctengineer.com/question.md?key=semester_6%2Foperating_system%3Apc-monitors-tsl) — Operating System, chapter 3
- [Critical section; mutual exclusion](https://www.bctengineer.com/question.md?key=semester_6%2Foperating_system%3Acritical-section-mutual-exclusion-pc) — Operating System, chapter 3
- [Race condition; critical section approaches](https://www.bctengineer.com/question.md?key=semester_6%2Foperating_system%3Arace-condition-critical-section-approaches) — Operating System, chapter 3

## Related in other subjects

- [Token ring mutual exclusion](https://www.bctengineer.com/question.md?key=semester_7%2Fdistributed_system%3Atoken-ring-mutex) — Distributed System, chapter 6, asked 3×
- [Ricart-Agrawala mutual exclusion](https://www.bctengineer.com/question.md?key=semester_7%2Fdistributed_system%3Aricart-agrawala) — Distributed System, chapter 6, asked 2×
- [Lamport algorithm for mutual exclusion](https://www.bctengineer.com/question.md?key=semester_7%2Fdistributed_system%3Alamport-mutex) — Distributed System, chapter 6
- [Mutual exclusion via sleep and wake](https://www.bctengineer.com/question.md?key=semester_6%2Fembedded_system%3Amutual-exclusion-sleep-wake) — Embedded System, chapter 6
