REFACTOR: This repository contains the evolved, production-ready version of my Operating Systems university assignment. The code has been completely refactored to enforce strict memory safety (zero memory leaks), prevent race conditions, and implement an
$O(1)$ thread-safe linked list for concurrent data aggregation.
This project demonstrates advanced system-level programming in C. It implements a highly synchronized Producer-Consumer architecture using the POSIX API. The system is designed to parse, filter, and process large datasets of binary strings using multiple concurrent threads while strictly avoiding deadlocks and race conditions.
The architecture is divided into two distinct execution phases:
- Multi-Processing (Data Filtering): The parent process uses
fork()andexecvp()to spawn an independent child process (data_filter.c) that sanitizes the raw input file, cross-platform carriage returns, and invalid characters. - Multi-Threading (Data Processing): The parent process launches a complex synchronization network utilizing
pthreadandsem_tcounting semaphores to distribute the workload.
- Language: C (C99 Standard)
- APIs: POSIX Threads (
pthreads), POSIX Semaphores (semaphore.h), UNIX Standard (unistd.h) - Build System: GNU Make
- Bounded Circular Buffer: A dynamically allocated shared buffer protected by Mutexes and Empty/Filled counting semaphores to regulate the flow between the Producer and the Consumers.
-
Thread-Safe Queue (Linked List): A dynamic linked list implementation featuring
$O(1)$ tail-insertion for Consumers and$O(1)$ head-extraction for the Aggregator thread, fully protected by its own distinct Mutex. - Poison Pill Shutdown: Implements a deterministic shutdown sequence where the Producer injects EOF "poison pills" into the buffer, allowing Consumers to exit gracefully without hanging.
-
Memory Safety (Valgrind Verified): Strict lifecycle management of dynamically allocated memory (
malloc/free), ensuring zero memory leaks even when threads dynamically discard data based on parity logic.
data_filterProcess: Readsinput.txt, strips invalid characters/carriage returns, and outputs clean binary strings tofiltered.txt.- Producer Thread: Reads
filtered.txtand pushes valid binary strings into the Circular Buffer. - Consumer Threads (N): Extract strings from the buffer, convert them to decimal integers, and calculate cumulative sums based on Thread ID parity. The partial sums are pushed into a Shared Linked List.
- Aggregator Thread: Pops the partial sums from the Linked List, calculates the final aggregated total, and writes the output to
results.txt.
This project requires a UNIX-like environment (Linux, macOS, or WSL on Windows) with gcc and make installed. A sample input.txt dataset is provided in the repository.
1. Clone the repository:
git clone [https://github.com/YOUR_USERNAME/OS-Concurrency-Producer-Consumer.git](https://github.com/YOUR_USERNAME/OS-Concurrency-Producer-Consumer.git)
cd OS-Concurrency-Producer-Consumer2. Compile the project using Make:
make clean && make
(This will safely compile both the data_filter and os_concurrency native executables).3. Run the architecture (e.g., 4 threads, buffer size 20):
./os_concurrency input.txt filtered.txt 4 20 results.txt4. View the multi-threaded aggregation results:
cat results.txtOriginal Authors
-Iván Moro Cienfuegos y Diego Martín García

