A complete implementation demonstrating concurrent job scheduling with System V IPC (message queues, shared memory) and pthreads. This system showcases SMT (Simultaneous Multithreading) awareness and priority-based scheduling behavior.
┌────────────┐ ┌────────────┐ ┌────────────┐
│ Producer 0 │ │ Producer 1 │ │ Producer 2 │
└─────┬──────┘ └─────┬──────┘ └─────┬──────┘
│ │ │
└───────────────┼───────────────┘
│ System V Message Queue
▼
┌──────────────────┐
│ SCHEDULER │
│ ┌────────────┐ │
│ │ Priority │ │
│ │ Queue │ │
│ └────────────┘ │
└────────┬─────────┘
│ Dispatch via Message Queue
┌───────────────┼───────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│Worker 0 │ │Worker 1 │ │Worker 2 │ ...
│┌───────┐│ │┌───────┐│ │┌───────┐│
││Thread ││ ││Thread ││ ││Thread ││
││ Pool ││ ││ Pool ││ ││ Pool ││
│└───────┘│ │└───────┘│ │└───────┘│
└─────────┘ └─────────┘ └─────────┘
- Multi-Producer Pattern: Multiple processes generating jobs concurrently
- Priority Queue: Scheduler sorts jobs by priority (Critical > High > Medium > Low)
- Thread Pool Workers: Each worker maintains a pool of 4 threads
- SMT-Aware Scheduling: CPU affinity and core pinning using
pthread_setaffinity_np() - System V IPC: Message queues (
msgget,msgsnd,msgrcv) and shared memory (shmget,shmat) - Process-Shared Mutexes: Thread-safe updates across processes using
PTHREAD_PROCESS_SHARED - Real-time Statistics: Periodic display of queue size, job counts, and worker loads
- Signal Handling: Graceful shutdown on SIGINT/SIGTERM
- Linux or WSL (Windows Subsystem for Linux)
- GCC compiler with pthread support
- POSIX-compliant system
# Navigate to project directory
cd linux-ipc-framework
# Build all executables
make
# View help
make help# Run automated demo
make run-demo
# Or run manually:
# Terminal 1: Start scheduler
./scheduler
# Terminal 2: Start workers
./worker 0 &
./worker 1 &
./worker 2 &
./worker 3 &
# Terminal 3: Start producers
./producer 0 20 &
./producer 1 20 &
./producer 2 20 &Open smt_scheduler_visualization.html in a web browser to see an interactive simulation.
linux-ipc-framework/
├── common.h # Shared data structures, constants, and macros
├── producer.c # Producer process - generates random jobs
├── scheduler.c # Central scheduler with priority queue
├── worker.c # Worker process with thread pool
├── Makefile # Build configuration
├── run_demo.sh # Demo automation script
├── smt_scheduler_visualization.html # Interactive HTML visualization
└── README.md # This file
Edit common.h to modify system parameters:
| Constant | Default | Description |
|---|---|---|
MAX_PRODUCERS |
3 | Number of producer processes |
MAX_WORKERS |
4 | Number of worker processes |
THREADS_PER_WORKER |
4 | Threads per worker pool |
MAX_QUEUE_SIZE |
100 | Maximum scheduler queue size |
MSG_QUEUE_KEY |
0x1234 | System V message queue key |
SHM_KEY |
0x5678 | System V shared memory key |
System V Message Queues:
// Create/connect to message queue
msg_queue_id = msgget(MSG_QUEUE_KEY, IPC_CREAT | 0666);
// Send message
msgsnd(msg_queue_id, &msg, sizeof(job_message_t) - sizeof(long), 0);
// Receive message (filtered by type)
msgrcv(msg_queue_id, &msg, sizeof(job_message_t) - sizeof(long), MSG_TYPE_JOB, IPC_NOWAIT);Shared Memory with Process-Shared Mutexes:
// Create and attach shared memory
shm_id = shmget(SHM_KEY, sizeof(shared_state_t), IPC_CREAT | 0666);
shared_mem = shmat(shm_id, NULL, 0);
// Initialize process-shared mutex
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&shared_mem->global_lock, &attr);Each worker maintains an internal thread pool with condition variables for job queuing:
typedef struct {
pthread_t threads[THREADS_PER_WORKER];
pthread_mutex_t queue_lock;
pthread_cond_t queue_cond;
job_queue_entry_t *queue_head;
job_queue_entry_t *queue_tail;
int queue_size;
int shutdown;
} thread_pool_t;Physical Core 0 Physical Core 1
┌──────────────────┐ ┌──────────────────┐
│ Log-0 │ Log-1 │ │ Log-2 │ Log-3 │
│ ↕↕↕ │ ↕↕↕ │ │ ↕↕↕ │ ↕↕↕ │
│ CONTENTION ZONE │ │ CONTENTION ZONE │
└──────────────────┘ └──────────────────┘
- Threads on the same physical core share execution resources
- SMT-aware worker selection prefers workers on different physical cores
- CPU pinning demonstrated with
pthread_setaffinity_np():
int pin_thread_to_core(int core_id) {
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(core_id, &cpuset);
return pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
}Jobs are sorted by priority in a linked-list priority queue:
- Critical (4): Processed first
- High (3): Second priority
- Medium (2): Third priority
- Low (1): Processed last
The scheduler selects workers based on current load and SMT topology.
| Type | Value | Purpose |
|---|---|---|
MSG_TYPE_JOB |
1 | Job submission from producer to scheduler |
MSG_TYPE_DISPATCH |
2+ | Job dispatch from scheduler to worker (offset by worker ID) |
MSG_TYPE_COMPLETE |
3 | Job completion notification from worker |
MSG_TYPE_SHUTDOWN |
99 | Shutdown signal |
# Remove executables
make clean
# Clean orphaned IPC resources (if demo crashes)
make clean-ipc| Issue | Solution |
|---|---|
| "Failed to create message queue" | Run make clean-ipc to remove stale IPC resources |
| "Permission denied" | Run chmod +x run_demo.sh |
| Scheduler hangs | Press Ctrl+C and run make clean-ipc |
| "Failed to connect to message queue" | Ensure scheduler is running first |
| Target | Description |
|---|---|
make |
Build all executables |
make debug |
Build with debug symbols (-g -O0) |
make clean |
Remove executables |
make clean-ipc |
Clean orphaned IPC resources |
make run-demo |
Run full automated demo |
make help |
Display usage instructions |
Educational project for demonstrating Linux systems programming concepts including IPC, threading, and CPU scheduling.