This repository contains implementations of fundamental Operating System concepts using C programming language in Linux and Windows environments.
- Process Creation using fork()
- Process Synchronization using Semaphores
- Producer-Consumer Problem
- Reader-Writer Problem (Linux - POSIX)
- Reader-Writer Problem (Windows API)
- Shared Memory IPC
- Common Concepts Used
- Learning Outcomes
- Linux Tools Used
- Conclusion
Click to expand/collapse
Process Creation and Process Identification
process_creation.c
To demonstrate process creation in Linux using the fork() system call and display the Process IDs (PIDs) of both parent and child processes.
The program works in the following steps:
- Initial Process: The program starts with a single parent process
- Fork System Call: When
fork()is called, it creates an exact copy of the parent process (called child process) - Process Differentiation:
fork()returns0to the child processfork()returns the child's PID (positive integer) to the parent processfork()returns-1if process creation fails
- PID Display: Both processes print their own Process IDs using
getpid() - Execution: Both parent and child processes execute independently after the fork
| Header File | Purpose |
|---|---|
stdio.h |
Provides input/output functions like printf() |
unistd.h |
Provides access to POSIX operating system API including fork() and getpid() |
Library Functions:
| Function | Purpose |
|---|---|
fork() |
Creates a new process by duplicating the calling process |
getpid() |
Returns the Process ID of the calling process |
printf() |
Prints formatted output to the console |
User-defined Functions:
- None (only
main()function)
| Variable | Type | Purpose |
|---|---|---|
pid |
pid_t |
Stores the return value of fork() to identify parent/child process |
Note: pid_t is a special data type for process IDs, typically an integer.
gcc process_creation.c -o process_creation./process_creationParent Process
Parent PID: 12345
Child Process
Child PID: 12346
Note: The order of output may vary as both processes run concurrently.
- Multi-processing: Creating multiple worker processes to handle different tasks
- Web Servers: Apache/Nginx create child processes to handle multiple client requests
- Shell Commands: When you run a command in terminal, the shell uses
fork()to create a child process - Background Jobs: Running processes in background while continuing with other tasks
Click to expand/collapse
Thread Synchronization using Binary Semaphore
process_synchronization.c
To demonstrate synchronization between multiple threads using semaphores to ensure mutual exclusion in the critical section.
The program demonstrates thread synchronization through these steps:
- Semaphore Initialization: A binary semaphore is initialized with value 1
- Thread Creation: Two threads (t1 and t2) are created
- Critical Section Entry:
- Thread calls
sem_wait(&sem)before entering critical section - If semaphore value is 1, it decrements to 0 and thread enters
- If semaphore value is 0, thread blocks and waits
- Thread calls
- Critical Section Execution: Only one thread can execute the critical section at a time
- Critical Section Exit: Thread calls
sem_post(&sem)which increments semaphore value, allowing other waiting threads to enter - Thread Termination: Both threads complete execution and are joined back to main thread
- Cleanup: Semaphore is destroyed
| Header File | Purpose |
|---|---|
stdio.h |
Provides standard input/output functions |
pthread.h |
Provides POSIX thread library functions for thread creation and management |
semaphore.h |
Provides semaphore functions for process/thread synchronization |
Library Functions:
| Function | Purpose |
|---|---|
sem_init() |
Initializes an unnamed semaphore with specified initial value |
sem_wait() |
Decrements (locks) the semaphore; blocks if value is 0 |
sem_post() |
Increments (unlocks) the semaphore |
sem_destroy() |
Destroys the semaphore object |
pthread_create() |
Creates a new thread to execute the given function |
pthread_join() |
Waits for the specified thread to terminate |
User-defined Functions:
| Function | Purpose |
|---|---|
task() |
Thread function that represents the critical section protected by semaphore |
| Variable | Type | Purpose |
|---|---|---|
sem |
sem_t |
Binary semaphore used for mutual exclusion |
t1, t2 |
pthread_t |
Thread identifiers for the two threads |
gcc process_synchronization.c -o process_synchronization -lpthreadNote: -lpthread flag is required to link the pthread library.
./process_synchronizationThread inside critical section
Thread inside critical section
Note: Only one thread executes at a time, preventing race conditions.
- Database Access: Ensuring only one transaction modifies a record at a time
- File Writing: Preventing multiple threads from writing to the same file simultaneously
- Resource Management: Controlling access to limited resources like printers, network connections
- Banking Systems: Ensuring atomic operations on account balances
Click to expand/collapse
Producer-Consumer Synchronization using Semaphores
producer_consumer.c
To implement the classic Producer-Consumer problem using semaphores to synchronize access to a shared buffer between producer and consumer threads.
This problem demonstrates inter-thread communication and synchronization:
- Semaphore Setup:
empty: Initialized to 1 (buffer is initially empty)full: Initialized to 0 (no items to consume initially)
- Producer Thread:
- Waits on
emptysemaphore (checks if buffer is empty) - Produces an item (buffer = 1)
- Signals
fullsemaphore (indicates item is available)
- Waits on
- Consumer Thread:
- Waits on
fullsemaphore (checks if item is available) - Consumes the item (buffer = 0)
- Signals
emptysemaphore (indicates buffer is empty)
- Waits on
- Synchronization: Semaphores ensure producer doesn't produce when buffer is full and consumer doesn't consume when buffer is empty
- Thread Completion: Both threads are joined and semaphores are destroyed
| Header File | Purpose |
|---|---|
stdio.h |
Standard input/output functions |
pthread.h |
Thread creation and management |
semaphore.h |
Semaphore operations for synchronization |
Library Functions:
| Function | Purpose |
|---|---|
sem_init() |
Initializes semaphores (empty and full) |
sem_wait() |
Waits (decrements) on semaphore; blocks if value is 0 |
sem_post() |
Signals (increments) semaphore to wake up waiting threads |
sem_destroy() |
Cleans up semaphore resources |
pthread_create() |
Creates producer and consumer threads |
pthread_join() |
Waits for threads to complete execution |
User-defined Functions:
| Function | Purpose |
|---|---|
producer() |
Thread function that produces items into the buffer |
consumer() |
Thread function that consumes items from the buffer |
| Variable | Type | Purpose |
|---|---|---|
empty |
sem_t |
Semaphore tracking empty buffer slots (initially 1) |
full |
sem_t |
Semaphore tracking full buffer slots (initially 0) |
buffer |
int |
Shared buffer (1 = item present, 0 = empty) |
p |
pthread_t |
Producer thread identifier |
c |
pthread_t |
Consumer thread identifier |
gcc producer_consumer.c -o producer_consumer -lpthread./producer_consumerProducer produced item
Consumer consumed item
- Print Spooler: Managing documents in a print queue
- Message Queues: Producer threads add messages, consumer threads process them
- Video Streaming: Producer decodes frames, consumer displays them
- Log Processing: Producer writes logs, consumer processes and stores them
- Data Pipelines: ETL (Extract, Transform, Load) operations
Click to expand/collapse
Reader-Writer Synchronization with Reader Priority (Linux/POSIX)
reader_writer.c
To implement the Reader-Writer problem using POSIX threads and semaphores, allowing multiple readers to read simultaneously while writers have exclusive access to shared data.
The program implements the first readers-writers problem solution with reader priority:
- Initialization:
writeLocksemaphore initialized to 1 (controls writer access)mutexsemaphore protects thereadCountvariablereadCounttracks number of active readersdatais the shared variable being read/written
- Reader Entry Protocol:
- Lock mutex to safely increment
readCount - If this is the first reader (readCount == 1), wait on
writeLockto block writers - Unlock mutex
- Perform reading operation (print current data value)
- Use
sleep(1)to simulate reading time
- Lock mutex to safely increment
- Reader Exit Protocol:
- Lock mutex to safely decrement
readCount - If this is the last reader (readCount == 0), signal
writeLockto allow writers - Unlock mutex
- Lock mutex to safely decrement
- Writer Protocol:
- Wait on
writeLocksemaphore for exclusive access - Perform writing operation (increment data by 10)
- Use
sleep(2)to simulate writing time - Signal
writeLockto release access
- Wait on
- Synchronization Logic:
- Multiple readers can read simultaneously
- Writer gets exclusive access (no readers or writers)
- First reader blocks writers, last reader unblocks them
- Reader priority: Writers may starve if readers keep coming
| Header File | Purpose |
|---|---|
stdio.h |
Standard input/output functions |
pthread.h |
Thread management for creating and joining threads |
semaphore.h |
Semaphore operations for synchronization |
unistd.h |
Provides sleep() function for simulating work |
Library Functions:
| Function | Purpose |
|---|---|
sem_init() |
Initializes the semaphores (mutex and writeLock) |
sem_wait() |
Waits (decrements) on semaphore; blocks if value is 0 |
sem_post() |
Signals (increments) semaphore to release lock |
sem_destroy() |
Destroys semaphores and releases resources |
pthread_create() |
Creates reader and writer threads |
pthread_join() |
Waits for thread completion |
sleep() |
Suspends thread execution for specified seconds |
User-defined Functions:
| Function | Purpose |
|---|---|
reader() |
Thread function for readers; takes reader ID as parameter, multiple can execute concurrently |
writer() |
Thread function for writers; executes with exclusive access |
| Variable | Type | Purpose |
|---|---|---|
data |
int |
Shared data variable being read and modified |
readCount |
int |
Counter for number of active readers |
mutex |
sem_t |
Semaphore protecting the readCount variable |
writeLock |
sem_t |
Semaphore ensuring exclusive writer access |
r1, r2, r3 |
pthread_t |
Reader thread identifiers |
w1 |
pthread_t |
Writer thread identifier |
id1, id2, id3 |
int |
Reader identification numbers (1, 2, 3) |
gcc reader_writer.c -o reader_writer -lpthread./reader_writerReader 1 is reading data = 0
Reader 2 is reading data = 0
Reader 3 is reading data = 0
Writer is writing data = 10
Note:
- Multiple readers can read simultaneously (all see data = 0)
- Writer waits for all readers to finish before writing
- Order may vary depending on thread scheduling
- Writer increments data by 10
- Database Management Systems: Multiple SELECT queries reading while occasional UPDATE/INSERT operations
- File Systems: Many processes reading a configuration file while admin occasionally updates it
- Cache Systems: Multiple threads reading cached data with periodic cache refresh
- Web Content Management: Many users viewing pages, few administrators editing content
- Document Collaboration: Multiple viewers reading while occasional edits occur
- Real-time Data Dashboards: Multiple clients reading metrics while data collectors update values
- Reader Priority: This implementation gives priority to readers, potentially starving writers
- Starvation Prevention: In real systems, writer priority or fair scheduling is often preferred
- Performance: Allows high read concurrency, beneficial for read-heavy workloads
- Thread IDs: Each reader has unique ID for tracking and debugging
Click to expand/collapse
Reader-Writer Synchronization using Windows API
reader_writer_windows.c
To implement the Reader-Writer problem using Windows threading API and semaphores, demonstrating cross-platform synchronization concepts with Windows-specific functions.
This Windows implementation follows the same reader-writer logic as the POSIX version:
- Initialization:
mutexsemaphore (binary, initial value 1) protectsreadCountwriteLocksemaphore (binary, initial value 1) controls writer accessreadCounttracks active readersdatais the shared variable
- Reader Entry Protocol:
WaitForSingleObject(mutex)locks mutex- Increment
readCount - First reader locks
writeLockto block writers ReleaseSemaphore(mutex)unlocks mutex- Read operation with reader ID display
Sleep(1000)simulates reading (1 second)
- Reader Exit Protocol:
- Lock mutex
- Decrement
readCount - Last reader releases
writeLock - Unlock mutex
- Writer Protocol:
WaitForSingleObject(writeLock)for exclusive access- Increment
databy 10 Sleep(1500)simulates writing (1.5 seconds)ReleaseSemaphore(writeLock)releases access
- Thread Management:
CreateThread()creates reader and writer threadsWaitForSingleObject()waits for thread completionCloseHandle()cleans up resources
| Header File | Purpose |
|---|---|
stdio.h |
Standard input/output functions |
windows.h |
Windows API functions including threading, synchronization, and sleep |
Library Functions:
| Function | Purpose |
|---|---|
CreateSemaphore() |
Creates a semaphore object with specified initial and maximum count |
WaitForSingleObject() |
Waits for semaphore to become signaled (available); blocks if not available |
ReleaseSemaphore() |
Increments semaphore count, signaling waiting threads |
CreateThread() |
Creates a new thread to execute specified function |
WaitForSingleObject() |
Also used to wait for thread termination (with thread handle) |
CloseHandle() |
Closes handles to threads and semaphores, releasing system resources |
Sleep() |
Suspends thread execution for specified milliseconds |
User-defined Functions:
| Function | Signature | Purpose |
|---|---|---|
reader() |
DWORD WINAPI reader(LPVOID param) |
Reader thread function; accepts reader ID as parameter |
writer() |
DWORD WINAPI writer(LPVOID param) |
Writer thread function; performs write operation |
| Variable | Type | Purpose |
|---|---|---|
readCount |
int |
Global counter for active readers |
data |
int |
Shared data variable being accessed |
mutex |
HANDLE |
Semaphore handle protecting readCount |
writeLock |
HANDLE |
Semaphore handle ensuring exclusive writer access |
r1, r2, r3 |
HANDLE |
Thread handles for three readers |
w1 |
HANDLE |
Thread handle for writer |
id1, id2, id3 |
int |
Reader identification numbers |
Windows-Specific Types:
HANDLE: Generic handle type for Windows objectsDWORD: 32-bit unsigned integer (return type for thread functions)WINAPI: Calling convention for Windows API functionsLPVOID: Long pointer to void (generic pointer type)
# Using MinGW on Windows
gcc reader_writer_windows.c -o reader_writer_windows.exe
# Using Microsoft Visual C++
cl reader_writer_windows.c# On Windows Command Prompt
reader_writer_windows.exe
# On PowerShell
.\reader_writer_windows.exeReader 1 is reading data = 0
Reader 2 is reading data = 0
Reader 3 is reading data = 0
Writer is writing data = 10
Note:
- All three readers can read simultaneously
- Writer waits until all readers finish
- Thread scheduling determines exact execution order
- Output order may vary between runs
| Feature | Windows API | POSIX (Linux) |
|---|---|---|
| Semaphore Creation | CreateSemaphore() |
sem_init() |
| Wait Operation | WaitForSingleObject() |
sem_wait() |
| Signal Operation | ReleaseSemaphore() |
sem_post() |
| Thread Creation | CreateThread() |
pthread_create() |
| Wait for Thread | WaitForSingleObject() |
pthread_join() |
| Cleanup | CloseHandle() |
sem_destroy() |
| Sleep Function | Sleep(milliseconds) |
sleep(seconds) |
| Thread Function | DWORD WINAPI func(LPVOID) |
void* func(void*) |
- Windows Services: Multi-threaded services handling multiple client requests
- COM Objects: Controlling concurrent access to shared Component Object Model resources
- Windows GUI Applications: Synchronizing UI thread with worker threads
- Game Development: Managing concurrent access to game state (DirectX applications)
- Database Drivers: ODBC drivers managing concurrent query execution
- System Utilities: Disk defragmenters, backup tools with concurrent operations
- Platform-Specific: Uses Windows API instead of POSIX standards
- Sleep Time:
Sleep()takes milliseconds (1000ms) vssleep()takes seconds (1s) - Handle Management: Uses Windows
HANDLEtype for all synchronization objects - Error Handling: Windows functions return
NULLon failure vs -1 in POSIX - Thread Return: Windows threads return
DWORDvs POSIX threads returnvoid*
✅ Native Windows support without additional libraries
✅ Better integration with Windows-specific features
✅ Consistent with Windows programming conventions
✅ No need for pthread library on Windows
Click to expand/collapse
Inter-Process Communication using Shared Memory
shared_memory_ipc.c
To demonstrate Inter-Process Communication (IPC) between parent and child processes using shared memory segments.
The program demonstrates shared memory communication:
- Shared Memory Creation:
shmget()creates a shared memory segment of 1024 bytesIPC_PRIVATEcreates a new segment0666sets read/write permissions- Returns a shared memory identifier (shmid)
- Shared Memory Attachment:
shmat()attaches shared memory to process address space- Returns a pointer to the shared memory
- Process Fork:
fork()creates a child process- Both parent and child have access to the same shared memory
- Parent Process:
- Writes a message to shared memory using
sprintf() - Detaches from shared memory using
shmdt() - Removes shared memory segment using
shmctl()
- Writes a message to shared memory using
- Child Process:
- Waits for parent to write data
- Reads and displays the message from shared memory
- Detaches from shared memory
- Synchronization:
sleep()ensures parent writes before child reads
| Header File | Purpose |
|---|---|
stdio.h |
Standard input/output functions |
sys/ipc.h |
Defines IPC operations and key generation |
sys/shm.h |
Provides shared memory operations (shmget, shmat, shmdt, shmctl) |
sys/types.h |
Defines data types used in system calls |
unistd.h |
Provides POSIX API including fork() and sleep() |
Library Functions:
| Function | Purpose |
|---|---|
shmget() |
Creates or accesses a shared memory segment |
shmat() |
Attaches shared memory segment to process address space |
shmdt() |
Detaches shared memory segment from process |
shmctl() |
Performs control operations (like removal) on shared memory |
fork() |
Creates child process |
sprintf() |
Writes formatted string to shared memory |
printf() |
Displays output to console |
sleep() |
Suspends execution for specified seconds |
perror() |
Prints error message for system call failures |
User-defined Functions:
- None (only
main()function)
| Variable | Type | Purpose |
|---|---|---|
shmid |
int |
Shared memory identifier returned by shmget() |
shared_memory |
char* |
Pointer to attached shared memory segment |
Constants Used:
IPC_PRIVATE: Creates a new private shared memory segmentIPC_CREAT: Flag to create shared memory if it doesn't existIPC_RMID: Flag to remove shared memory segment
gcc shared_memory_ipc.c -o shared_memory_ipc./shared_memory_ipcParent: Writing to shared memory...
Child: Waiting for data...
Child: Data read from shared memory: Hello from Parent Process!
- High-Speed Communication: Faster than pipes or message queues for large data
- Database Systems: Shared buffer pools accessible by multiple processes
- Graphics Systems: X Window System uses shared memory for faster rendering
- Multimedia Applications: Video/audio players share frame buffers between processes
- Scientific Computing: Parallel processing applications sharing large datasets
Click to expand/collapse
- Process: An instance of a running program with its own memory space
- Process Creation: Using
fork()system call to create child processes - Process ID (PID): Unique identifier for each process
- Thread: Lightweight process sharing memory space with other threads
- Multi-threading: Creating multiple threads within a single process
- Thread Synchronization: Coordinating thread execution to avoid race conditions
- Purpose: Synchronization primitive for process/thread coordination
- Types:
- Binary Semaphore: Values 0 or 1 (like mutex)
- Counting Semaphore: Values 0 to N (resource counting)
- Operations:
wait()(P operation): Decrement semaphore, block if 0signal()(V operation): Increment semaphore, wake waiting process
- Purpose: Ensures only one thread accesses critical section
- Operations:
lock(): Acquire mutexunlock(): Release mutex
- Critical Section: Code segment accessing shared resources
- Requirements:
- Mutual Exclusion: Only one process in critical section
- Progress: Decision on entry cannot be postponed indefinitely
- Bounded Waiting: Limit on waiting time for entry
- Shared Memory: Fastest IPC method, direct memory access
- Advantages: High speed, efficient for large data
- Disadvantages: Requires explicit synchronization
| Problem | Description | Solution |
|---|---|---|
| Producer-Consumer | Coordinating data production and consumption | Two semaphores (empty, full) |
| Reader-Writer | Multiple readers or single writer | Semaphore + Mutex + Counter |
| Dining Philosophers | Avoiding deadlock with limited resources | Resource ordering or semaphore arrays |
| Concept | Windows API | POSIX (Linux) |
|---|---|---|
| Threading | Windows Threads | POSIX Threads (pthreads) |
| Synchronization | Semaphores, Mutexes, Events | Semaphores, Mutexes, Condition Variables |
| Sleep Function | Sleep(milliseconds) |
sleep(seconds), usleep(microseconds) |
| Thread Creation | CreateThread() |
pthread_create() |
Click to expand/collapse
After completing these programs, students will understand:
- ✅ How processes are created using
fork() - ✅ Difference between parent and child processes
- ✅ Process identification using PIDs
- ✅ Independent execution of processes
- ✅ Creating and managing threads using POSIX threads
- ✅ Creating threads using Windows API
- ✅ Difference between processes and threads
- ✅ Thread synchronization techniques
- ✅ Joining threads and cleanup
- ✅ Using semaphores for mutual exclusion
- ✅ Implementing mutex locks
- ✅ Solving race conditions
- ✅ Understanding deadlock and how to prevent it
- ✅ Reader-writer priority mechanisms
- ✅ Producer-Consumer problem solution
- ✅ Reader-Writer problem with reader preference
- ✅ Understanding reader priority vs writer priority
- ✅ Importance of proper synchronization
- ✅ Preventing starvation
- ✅ Shared memory creation and management
- ✅ Process communication without using files or pipes
- ✅ Synchronizing access to shared resources
- ✅ Efficient data sharing between processes
- ✅ Using Linux system calls
- ✅ Using Windows API functions
- ✅ Error handling in system programming
- ✅ Resource cleanup and management
- ✅ Compilation with special libraries
- ✅ Cross-platform considerations
- ✅ Debugging multi-threaded programs
- ✅ Understanding concurrent execution
- ✅ Writing thread-safe code
- ✅ Memory management in IPC
- ✅ Platform-specific API usage
- ✅ Choosing appropriate synchronization primitives
- ✅ Reader counting mechanism
- ✅ Multiple readers with single writer coordination
- ✅ Thread parameter passing
- ✅ Proper resource initialization and destruction
- ✅ Understanding race conditions and their prevention
Click to expand/collapse
- Purpose: C/C++ compiler for Linux
- Usage: Compiling C programs into executable files
- Common Flags:
-o: Specify output file name-lpthread: Link pthread library-Wall: Enable all warnings-g: Include debugging information
- Library:
pthread.h - Purpose: Standard for thread creation and management
- Features:
- Thread creation and termination
- Thread synchronization (mutex, condition variables)
- Thread attributes configuration
- Linking: Requires
-lpthreadflag during compilation
- Library:
semaphore.h - Purpose: Synchronization primitive for process/thread coordination
- Types:
- Named semaphores (process-shared)
- Unnamed semaphores (thread-shared)
- Functions:
sem_init(),sem_wait(),sem_post(),sem_destroy()
- Libraries:
sys/shm.h,sys/ipc.h - Purpose: Fastest IPC mechanism for data sharing
- System Calls:
shmget(): Create/get shared memory segmentshmat(): Attach segment to address spaceshmdt(): Detach segmentshmctl(): Control operations (remove, stat)
- Library:
unistd.h - Provides:
- Process management (
fork(),getpid()) - File operations
- Process control (
sleep(),exec())
- Process management (
| Tool | Purpose |
|---|---|
| MinGW | Minimalist GNU for Windows - GCC port for Windows |
| Visual Studio | Microsoft's IDE with MSVC compiler |
| Windows SDK | Software Development Kit for Windows API |
| Visual C++ | Microsoft C/C++ compiler |
| Tool | Purpose | Platform |
|---|---|---|
gdb |
GNU debugger for debugging programs | Linux |
valgrind |
Memory leak detection and profiling | Linux |
strace |
Trace system calls and signals | Linux |
ps |
Display running processes | Linux |
top/htop |
Monitor system processes | Linux |
ipcs |
Display IPC facilities (shared memory, semaphores) | Linux |
ipcrm |
Remove IPC resources | Linux |
| Visual Studio Debugger | Integrated debugger | Windows |
| WinDbg | Windows debugger | Windows |
| Process Explorer | Advanced process monitoring | Windows |
# Linux Commands
# View shared memory segments
ipcs -m
# Remove shared memory segment
ipcrm -m <shmid>
# View semaphores
ipcs -s
# Check process tree
pstree
# Monitor thread activity
ps -eLf
# Real-time process monitoring
htop
# Compile with threading support
gcc program.c -o program -lpthread
# Check thread count
ps -T -p <pid>REM Windows Commands
REM List running processes
tasklist
REM Kill a process
taskkill /PID <process_id>
REM Monitor system resources
resmon
REM Process information
wmic process list brief
REM Compile with MinGW
gcc program.c -o program.exe
REM Compile with Visual C++
cl program.cClick to expand/collapse
This laboratory work covered essential Operating System concepts implemented in C on both Linux and Windows platforms:
-
Process Management: Successfully demonstrated process creation using
fork()and understanding of parent-child process relationships -
Concurrency: Implemented multi-threaded programs using both POSIX threads (Linux) and Windows API, understanding concurrent execution and its challenges
-
Synchronization: Solved critical section problems using semaphores and mutex locks, preventing race conditions and ensuring data consistency
-
Classic Problems: Implemented standard OS synchronization problems (Producer-Consumer, Reader-Writer) that form the foundation of modern concurrent systems with detailed analysis of reader priority
-
Inter-Process Communication: Demonstrated high-speed data sharing between processes using shared memory
-
Cross-Platform Development: Implemented the same synchronization problem using both POSIX and Windows API, understanding platform-specific differences and portability considerations
These concepts are fundamental to:
- Modern Software Development: Multi-threaded applications, concurrent servers
- System Programming: Operating systems, device drivers, embedded systems
- Distributed Systems: Microservices, cloud computing, parallel processing
- Real-time Systems: Industrial automation, robotics, telecommunications
- Cross-Platform Applications: Understanding API differences between Windows and Linux
✅ Always check return values of system calls
✅ Properly initialize and destroy synchronization primitives
✅ Clean up resources (semaphores, shared memory, threads)
✅ Use appropriate synchronization for shared data
✅ Compile with -lpthread when using POSIX threads
✅ Handle errors gracefully with perror() or error codes
✅ Consider platform-specific differences in cross-platform development
✅ Use meaningful thread IDs for debugging
✅ Prevent starvation with fair scheduling policies
Linux/POSIX:
- More portable across Unix-like systems
- Standard POSIX compliance
- Better for server and embedded systems
- Rich command-line tools for debugging
Windows:
- Native Windows integration
- Better for Windows desktop applications
- Consistent with Windows programming patterns
- Visual Studio debugging tools
Students are encouraged to:
- Implement writer priority in Reader-Writer problem
- Experiment with multiple producers and consumers
- Implement additional synchronization problems (Dining Philosophers, Sleeping Barber)
- Explore other IPC mechanisms (pipes, message queues, sockets)
- Study deadlock detection and prevention algorithms
- Port programs between Linux and Windows
- Implement fair scheduling to prevent starvation
- Add error recovery mechanisms
- Measure performance differences between synchronization methods
Understanding these concepts enables developers to:
- Build scalable web servers handling thousands of concurrent connections
- Develop responsive GUI applications with background processing
- Create efficient database systems with concurrent access control
- Design real-time systems with predictable behavior
- Write portable code that works across multiple platforms
- POSIX Threads Programming: https://computing.llnl.gov/tutorials/pthreads/
- Windows Threading Documentation: Microsoft Docs - Processes and Threads
- Linux Man Pages: Use
man fork,man pthread_create,man sem_init, etc. - Operating System Concepts by Silberschatz, Galvin, and Gagne
- The Linux Programming Interface by Michael Kerrisk
- Windows System Programming by Johnson M. Hart
Laboratory: Operating Systems Lab
Academic Year: 2024-2025
Platform: Linux (Ubuntu/Debian) and Windows 10/11
Compiler: GCC (Linux/MinGW), Visual C++ (Windows)
End of Documentation