Programming lesson
C Programming: Simulating Black Friday Crowd Control with Multi-Threading and Mutexes
Learn how to simulate a Black Friday crowd control system using C multi-threading and mutual exclusion. This tutorial covers pthreads, mutexes, and semaphores with a real-world store scenario.
Introduction: Black Friday Crowd Control in C
Black Friday is the biggest shopping event of the year, and managing crowds is critical for safety. In this tutorial, you'll learn how to simulate a store's customer flow using C multi-threading and mutual exclusion. We'll use the pthread library and mutexes to coordinate two escort teams moving 500 shoppers from the main entrance to four zones. This assignment teaches you how to safely update shared values in a concurrent environment—a skill essential for system programming, game development, and high-performance apps.
Why Multi-Threading Matters in 2026
From AI chatbots to real-time multiplayer games, multi-threading is everywhere. For example, a viral shopping app like ShopDrop uses threads to handle thousands of users simultaneously. Understanding mutexes and semaphores helps you prevent race conditions, just like our Black Friday simulation prevents chaos in the store.
Understanding the Problem
You have 500 shoppers at the main entrance (Zone 0). They want to reach four zones:
- Zone 1 (Appliances): 50 shoppers
- Zone 2 (TVs): 100 shoppers
- Zone 3 (Smartphones): 250 shoppers
- Zone 4 (Video Games): 100 shoppers
Two escort teams guide shoppers: Team 0 can handle up to 100 shoppers at a time, Team 1 up to 50. Only one team can be in a zone at once. You must simulate this using threads for each team and a mutex for each zone.
Setting Up the Simulation
We'll use pthreads to create two threads (one per escort team). Each thread will loop until all shoppers are delivered. We'll use mutexes to ensure exclusive access to each zone. Here's the plan:
- Initialize mutexes for each zone.
- Create two threads:
escort_team_0andescort_team_1. - Each thread picks a zone with remaining shoppers, locks its mutex, moves shoppers (up to its capacity), updates the count, unlocks, and repeats.
- Main thread waits for both threads to finish, then destroys mutexes.
Code Walkthrough
First, define shared variables: int remaining[4] = {50, 100, 250, 100}; for each zone. Also, pthread_mutex_t zone_mutex[4];. In the thread function, use a loop:
while (1) {
int zone = pick_zone(); // find a zone with remaining > 0
if (zone == -1) break;
pthread_mutex_lock(&zone_mutex[zone]);
int move = (remaining[zone] < capacity) ? remaining[zone] : capacity;
remaining[zone] -= move;
printf("Team %d moved %d shoppers to Zone %d
", team_id, move, zone);
pthread_mutex_unlock(&zone_mutex[zone]);
}Note: pick_zone() should be atomic or use a separate mutex to avoid data races. Alternatively, use a single mutex for the whole selection process.
Using Semaphores Instead
You can also use semaphores. Initialize each zone semaphore to 1 (binary semaphore). The thread does sem_wait(&zone_sem[zone]) before moving shoppers and sem_post() after. Semaphores are useful when you need to control access to a resource pool.
Complete Example
Here's a simplified working version:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
int remaining[4] = {50, 100, 250, 100};
pthread_mutex_t zone_mutex[4];
pthread_mutex_t select_mutex = PTHREAD_MUTEX_INITIALIZER;
int pick_zone() {
for (int i = 0; i < 4; i++) {
if (remaining[i] > 0) return i;
}
return -1;
}
void* escort(void* arg) {
int capacity = *(int*)arg;
while (1) {
pthread_mutex_lock(&select_mutex);
int zone = pick_zone();
if (zone == -1) { pthread_mutex_unlock(&select_mutex); break; }
pthread_mutex_lock(&zone_mutex[zone]);
int move = (remaining[zone] < capacity) ? remaining[zone] : capacity;
remaining[zone] -= move;
printf("Moved %d to zone %d
", move, zone);
pthread_mutex_unlock(&zone_mutex[zone]);
pthread_mutex_unlock(&select_mutex);
}
return NULL;
}
int main() {
pthread_t t0, t1;
int cap0 = 100, cap1 = 50;
for (int i = 0; i < 4; i++) pthread_mutex_init(&zone_mutex[i], NULL);
pthread_create(&t0, NULL, escort, &cap0);
pthread_create(&t1, NULL, escort, &cap1);
pthread_join(t0, NULL);
pthread_join(t1, NULL);
for (int i = 0; i < 4; i++) pthread_mutex_destroy(&zone_mutex[i]);
return 0;
}Testing and Debugging
Compile with gcc -pthread black_friday.c -o black_friday. Run multiple times to ensure no race conditions. You can add sleep(1) inside the critical section to simulate time and increase chance of context switches.
Trend Connection: AI and Black Friday 2026
In 2026, AI-driven inventory systems use similar concurrency patterns to manage stock across warehouses. For example, Amazon's fulfillment centers use multiple robots (threads) that access shared shelf locations (zones) with mutexes to avoid collisions. This simulation mirrors that real-world problem.
Common Pitfalls
- Deadlock: If two threads each lock one mutex and wait for another, they can deadlock. Always lock mutexes in a consistent order.
- Starvation: A thread might never get a chance to run. Use fair scheduling or yield.
- Race conditions: Forgetting to lock shared variables leads to incorrect counts. Always protect shared data.
Conclusion
You've learned to simulate Black Friday crowd control using C multi-threading and mutual exclusion. This core concept applies to operating systems, game engines, and high-traffic web servers. Practice by adding more zones or varying team capacities. Happy coding!