Cigarette Smokers Problem
By Michael Thompson, for Mirkwood only
CMAC 4000 - Operating Systems
Overview
The Cigarette Smokers Problem was introduced by Suhas Patil (1971) as a synchronization puzzle illustrating the limits of semaphores and the difficulty of coordinating multiple consumers with overlapping resource needs.
Three smokers sit around a table. Each smoker has an infinite supply of exactly one ingredient:
- Tobacco
- Paper
- Matches
A fourth process, the agent, has an infinite supply of all three. To smoke a cigarette, a smoker needs all three ingredients. The agent repeatedly places two of the three items on the table. The smoker who has the third item should take the two from the table, make a cigarette, smoke, and then signal the agent to continue.
Why the Problem Is Interesting
Unlike the Dining Philosophers problem, the Cigarette Smokers problem is provably impossible to solve using only classical Dijkstra semaphores under Patil's original constraints. These constraints forbid the agent from directly waking a specific smoker or revealing which ingredients are available.
Modern textbook versions relax these constraints, allowing the agent to signal the correct smoker. Under these relaxed rules, a clean semaphore-based solution is possible.
Standard Semaphore-Based Solution (Relaxed Rules)
The practical solution:
- One semaphore per smoker (initially 0)
- A table mutex semaphore (initially 1)
- An
agent_donesemaphore so the agent waits until the smoker finishes
This avoids the race where two smokers each take one ingredient and both block forever waiting for the other.
Agent Pseudocode
semaphore table = 1
semaphore smoker_tobacco = 0
semaphore smoker_paper = 0
semaphore smoker_match = 0
semaphore agent_done = 0
agent():
while true:
wait(table)
choose random pair
if (paper, match): signal(smoker_tobacco)
if (tobacco, match): signal(smoker_paper)
if (tobacco, paper): signal(smoker_match)
wait(agent_done)
signal(table)
Smoker Pseudocode (example: smoker with tobacco)
smoker_with_tobacco():
while true:
wait(smoker_tobacco)
// take paper and match
make_and_smoke()
signal(agent_done)
Why a Naive Semaphore Solution Fails
If smokers wait on semaphores for individual ingredients (e.g., one semaphore for paper, one for matches), two smokers may each take one ingredient and then deadlock waiting for the other. Patil showed that under his strict rules, this cannot be solved with semaphores alone.
The key issue is that semaphores cannot express the conditional logic "wake exactly the smoker who has the missing ingredient" without violating Patil's constraints.
Relation to Other Classic Problems
- Dining Philosophers: All resources are interchangeable; deadlock arises from circular wait.
- Cigarette Smokers: Resources are not interchangeable; the challenge is matching a specific consumer to a specific resource pair.
This makes the Cigarette Smokers problem a stronger demonstration of the limits of semaphores than Dining Philosophers.
References
- Patil, Suhas. - Limitations and Capabilities of Dijkstra's Semaphore Primitives for Coordination among Processes (1971)
- JMU CSF - Cigarette Smokers Problem and the Limits of Semaphores and Locks
- Allen B. Downey - Little Book of Semaphores (online edition)
- David Parnas - ON A SOLUTION TO THE CIGARETTE SMOKERS' PROBLEM (without conditional statements)