This project is an exercise for the Advanced Operating Systems course at Harokopio University of Athens, Dept. of Informatics and Telematics. It implements a worker pool paradigm using processes and pipes for inter-process communication. The parent process distributes tasks to child processes, which execute them and respond with results. The program ensures proper synchronization using semaphores and supports a graceful shutdown on receiving termination signals (e.g., SIGINT or SIGTERM). Additionally, the project incorporates Remote Procedure Call (RPC) functionality to facilitate client-server communication, allowing remote execution of operations (currently, only the addition of 5 numbers is supported).
- Task distribution to child processes.
- Bidirectional communication using pipes.
- Semaphore-based synchronization.
- Graceful shutdown with resource cleanup.
- Dynamic handling of tasks and child processes.
- Support for different worker types to handle heterogeneous workloads.
- Remote Procedure Call (RPC) support for executing operations remotely.
The RPC mechanism enables a client to send computation requests to the server, which delegates the tasks to worker processes. The results are then sent back to the client.
- RPC Server: Listens for client requests and distributes tasks to workers.
- RPC Client: Sends computation requests to the server and receives responses.
- Worker Pool: Processes the assigned tasks and returns results.
- Inter-Process Communication (IPC): Pipes are used for worker-server communication, while semaphores handle synchronization.
Addition Operation: Clients can send a set of numbers (5) to the server for summation.
Worker-based Parallel Processing: The server assigns computations to available workers, ensuring efficiency.
The program supports different worker profiles to handle various workloads efficiently. Each worker type is specialized to process specific kinds of tasks:
-
General Worker: Handles standard tasks that do not require specialized processing.
-
I/O Worker: Focused on handling I/O-bound tasks such as reading/writing files or network communication.
-
Computation Worker: Handles CPU-intensive tasks such as mathematical calculations and data processing.
-
Mixed Worker: Capable of handling both I/O-bound and computation-heavy tasks, providing flexibility in workload distribution.
Each task is categorized based on its workload type:
-
General Task: A standard task that does not require specific handling.
-
I/O Task: Involves file operations, database queries, or other I/O-intensive operations.
-
Computation Task: Requires CPU-intensive processing, such as simulations or numerical computations.
Tasks are assigned to workers based on their specialization, ensuring efficient resource utilization and optimized execution times.
Ensure you have installed in your system the following:
- GCC compiler (for compiling C code).
- Linux environment (for pipe and semaphore usage).
make(for building the project).rpcbind(to manage RPC calls).
To compile and run the program, use the provided Makefile. Simply run:
make
make run OUTPUT_FILE=output.txt NUM_PROCESSES=5<OUTPUT_FILE>: Name of the file where child outputs will be logged.<NUM_PROCESSES>: Number of child processes (positive integer).
Note that, for these commands to work, you need to be in the /Advanced_OS directory.
To compile the RPC server, run:
gcc -o add_server add_svc.c add_server.c add_xdr.c -I/usr/include/tirpc -ltirpcTo start the RPC server, run:
./add_serverNote that, for the server commands to work, you need to be in the /Advanced_OS/RPC-add directory.
To compile the RPC client, run:
gcc -o add_client add_clnt.c add_client.c add_xdr.c -I/usr/include/tirpc -ltirpcTo send requests to the RPC server, run:
./add_client <server_host> num1 num2 num3 num4 num5The client will attempt to connect to the server and send a task request. The server will process the request and return the result.
Explementary client execution:
./add_client localhost 10 20 30 40 50Note that, for the client commands to work, you need to be in the /Advanced_OS/RPC-add directory.
Build the image:
docker build -t rpc_server .Run the container:
docker run -it --name rpc_server rpc_serverIn case the container already exists, remove it:
docker rm -f rpc_serverExecute the command:
make -f Makefile.addGet the container’s IP address with:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' rpc_serverRun the client (with the ip that was displayed):
./add_client <container_ip_address> num1 num2 num3 num4 num5Compile the program:
gcc -Wall -o main main.cExecute the program:
./main <filename> <#processes><filename>: Name of the file where child outputs will be logged.<#processes>: Number of child processes (positive integer).
Explementary execution:
./main output.txt 5- SIGINT: Triggers a graceful shutdown (Ctrl+C).
- SIGTERM: Triggers a graceful shutdown.
main.c: Entry point for the worker-based task distribution systemMakefile: Build automation file to compile the project.add_server.c: Server-side implementation for the RPC system.add_client.c: Client-side implementation for making RPC requests.add_svc.c: Generated RPC service skeleton for the server.add_xdr.c: XDR (External Data Representation) serialization/deserialization logic.README.md: Documentation and instructions for running the project.- and more...
To remove compiled binaries:
- For the worker-based task distribution system, run:
make clean- For the RPC client-server system, run:
make -f Makefile.add clean- Name: Exarchou Athos
- Student ID: it2022134
- Email: [email protected], [email protected]
This project is licensed under the MIT License.