Explore the Party Room
Before diving into the ring buffer, let's get comfortable with the tools you'll be using: POSIX mutexes and condition variables.
We've provided a small demo program called party.c that simulates
a party in a room with limited capacity. Guests arrive, wait if
the room is full, dance for a while, and leave. party is short, it
compiles, it runs, and it uses every pthreads pattern you'll need
for the ring-buffer lab.
Build and Run
In your lab directory, run
make party
./party
Run the program a few times—you'll get different output each time because
of randomness in arrival times and dance durations. Watch for the
>> (enter) and << (leave) markers, and notice that the room
count never exceeds its capacity.
Read the Code
Open party.c in your editor, or if your syntax highlighting makes
comments hard to read, try reading the code with
less party.c
You will find that party.c is heavily commented. Pay particular
attention to the
- Error-Checking Macros
CHECK_PTHREADandCHECK_SYSCALLnear the top. These handle the two different error-reporting conventions used by pthreads functions vs. traditional system calls. You can steal this code and use it in your ring-buffer code, or just do the checking by hand every single time like an animal. Your call.whileLoop Aroundpthread_cond_waitin the Guest Thread- The comments explain why this loop must use
whileand notif. This is the single most common concurrency bug, because you will be tempted to writeifin the ring buffer. Don't. - Unlock-Before-Slow-Work Pattern
- The guest releases the mutex before sleeping (dancing), so other guests can enter and leave while they party. Your ring buffer will need the same discipline—release the lock before printing or sleeping.
pthread_cond_signalCall When a Guest Leaves- This call wakes up one waiting guest. Think about when and why signaling is needed.
Experiment
The #defines at the top of party.c control the simulation.
Try changing them, recompiling, and seeing what happens. Some
things to try:
-
Set
ROOM_CAPACITYto 1. Now only one guest can be inside at a time. What does the output look like? -
Set
MAX_ARRIVE_MSto 0 so everyone shows up at once. How many guests end up waiting? -
Set
ROOM_CAPACITYto 20 (equal toNUM_GUESTS). Does anyone have to wait? -
Make the dance times very long (e.g.,
MIN_DANCE_MS = 3000,MAX_DANCE_MS = 5000) and the arrival times very short. What happens to the waiting line?
You don't need to write anything down—just build some intuition about how mutexes and condition variables behave.
Connecting The Party to the Ring Buffer
The party room and the ring buffer solve the same fundamental problem: coordinating access to a limited shared resource.
| Party Room | Ring Buffer |
|---|---|
| Room capacity | Number of buffer slots |
| "Room is full, wait" | Producer waits for an empty slot |
| "Room is empty" | Consumer waits for a filled slot |
| Guest enters | Producer fills a slot |
| Guest leaves | Consumer empties a slot |
| Signal after leaving | Signal after consuming (or producing) |
When you start on ringbuf.c, you'll have two reasons for
waiting—buffer full and buffer empty—instead of one, which means
you'll need to think about what conditions to use. But the core
pattern—lock, check in a loop, wait, do your thing, signal,
unlock—is exactly what you've just seen.
(When logged in, completion status appears here.)