Multi-threaded web server
Introduction
This project is really two projects grouped together, one in C and one in Rust. Both projects do the same thing, i.e. they are both Unix shells. The C project is simply called multi-threaded-web-server
(for lack of a better name) and the Rust project is called fibre
(because of multi-threading, get it?). The C project is the original project, and the Rust project is a rewrite of the C project in order to learn more about Rust.
About the project
This project was a part of the course "Operating Systems" at NTNU. The goal was to create a multi-threaded web server, written in C, that could handle multiple requests at the same time. The server should be able to handle multiple concurrent requests from multiple clients at the same time.
In short, the multi-threaded web server to serves static file content to the client using sockets.
The application initializes a server responsible for adding a client's file descriptor to a FIFO queue. Additionally, the application initializes a thread pool of worker threads responsible for getting a file descriptor from the queue and serving content to the client.
Insertion into and retrieval from the queue is implemented using my custom implementation of semaphores from scratch using mutexes and condition variables.
Differences in developer experience between C and Rust
Concurrency
One of the main differences is that Rust has a strong emphasis on safe concurrency, whereas C does not. In Rust, concurrency is supported through the use of threads, which are multiple independently executing parts of a program. Rust provides a number of features to help ensure the safety of concurrent code, such as the Arc
(atomic reference count) type for shared ownership and the Mutex
(mutual exclusion) type for mutual exclusion.
In the C project, the concept of semaphores was implemented from scratch. This was done by using mutexes and condition variables. The mutexes were used to ensure that only one thread at a time could access the critical section of code, and the condition variables were used to ensure that the threads were notified when the critical section of code was available.
Overall, Rust provides a more opinionated and safer approach to concurrency, while C provides more flexibility and control, but at the cost of additional complexity and the need for the developer to ensure the safety of concurrent code.
Read more
Read more about multi-threaded-web-server
and fibre
by clicking their respective links.