HW3b: HTTP Server, phase B

Part 5: Multi-threaded web server

POSIX threads provide a light-weight alternative to child processes. Instead of creating child processes to handle multiple HTTP requests simultaneously, we will create a new POSIX thread for each HTTP request.

Tasks

  1. Modify the original skeleton code (i.e., part0/http-server.c) so that the web server creates a new POSIX thread after it accepts a new client connection, and the new thread handles the request and terminates afterwards.

  2. Two library functions used by the skeleton http-server.c are not reentrant, therefore not thread-safe. You must replace them with their thread-safe counterparts in your code.

    In your README.txt, identify the two functions and describe how you fixed them.

  3. Test this implementation by connecting to it from multiple netcat clients simultaneously.

  4. Perform benchmark measurements as you did in part 0 and part 1. Do you see any improvement over the skeleton version (part 0)? Any improvement over the multi-process version from part 1?

Requirements and hints

Deliverables

  1. The new version of http-server.c

  2. README.txt: how you fixed the two non-reentrant function calls

  3. Performance testing result

Part 6: Pre-created pool of threads

Reading

Read the following Q&A at StackOverflow.com:

In part 6 & 7, we will implement the two methods described in the article and compare the performances.

Tasks

  1. Instead of creating a new thread for each new client connection, pre-create a fixed number of worker threads in the beginning. Each of the pre-created worker threads will act like the original skeleton web server – i.e., each thread will be in a for(;;) loop, repeatedly calling accept().

  2. Test this implementation by connecting to it from multiple netcat clients simultaneously.

  3. Perform benchmark testing. How does it compare with part 5?

Requirements and hints

Deliverables

  1. The new version of http-server.c

  2. Performance testing result

Part 7: Blocking queue

Tasks

  1. Modify the code so that only the main thread calls accept(). The main thread puts the client socket descriptor into a blocking queue, and wakes up the worker threads which have been blocked waiting for client requests to handle.

  2. Test this implementation by connecting to it from multiple netcat clients simultaneously.

  3. Perform benchmark testing. How does it compare with part 6?

Requirements and hints

Deliverables

  1. The new version of http-server.c

  2. Performance testing result

Part 8: Listening on multiple ports

Tasks

  1. Modify the code so that the web server takes not just one, but multiple port numbers as command line arguments (followed by the web root as the last argument.) The web server will bind and listen on all of the ports.

  2. Test this implementation by connecting to it from multiple netcat clients simultaneously to different ports.

  3. Perform benchmark testing, hitting multiple ports. Compared to part 7, performance penalty should be negligible, if any.

Requirements and hints

Deliverables

  1. The new version of http-server.c

  2. Performance testing result

Part 9: Nonblocking accept()

Part 8 has a flaw. Between select() and accept(), there is a chance that the client connection gets reset. If that happens, accept() will block. In order to handle that case, we need to make the server socket nonblocking.

Tasks

  1. Modify the code so that createServerSocket() sets the server socket into a nonblocking mode.

  2. Now accept() will never block. In those cases where it would have blocked, it will now fail with certain errno values. Read the man page to find out which errno values you need to handle.

  3. Perform benchmark testing.

Deliverables

  1. The new version of http-server.c

  2. Performance testing result

Good luck!


Acknowledgment

This series of assignments were co-designed by Jae Woo Lee and Jan Janak as a prototype for a mini-course on advanced UNIX systems and network programming.

Jan Janak wrote the solution code.

Jae Woo Lee is a lecturer, and Jan Janak is a researcher, both at Columbia University. Jan Janak is a founding developer of the SIP Router Project, the leading open-source VoIP platform.


Last updated: 2014–02–21