3013 Project 4

Threaded Electronic Handball Server

Due date: Thursday October 14th, by Midnight

Warning! You must have your project in by Midnight on Friday, October 16th at the latest! Projects will not be accepted after this time! We need to get all the projects graded as quickly as possible to evaluate course grades.



There are two parts to this assignment. The first involves modifying your server from your project 3 to use threads. The second part involves some simple performance comparisons between processes and threads. Most of this document describes how to modify your server. The Performance section describes the comparisons you are to do.

Threaded Server

You are to make the Electronic Handball Server in Project 3 multi-threaded. The external functionality of the server and the client will remain identical to that of Project 3, but internally the server will have multiple threads of control.

The main server thread will wait on the socket, accepting connections. Upon receiving a connection (via the sockaccept() call), the server will spawn a new thread to handle the connection. The main thread will then loop back up to accept more connections. Thus, there will be a new thread created per connection.

As usual, all system calls, including those involving threads, should be error checked. In most cases, the server can simply exit if a system call fails, but this should be done on a per thread basis, and not a per process basis as before (ie- use pthread_exit(NULL) instead of exit()).

Since the server will no longer need to communicate to other fork'ed processes, shared memory will not be needed (or select(), if you used the single server process solution to your project 3). Instead, all the server threads will share data through global variables. Since multiple threads may be accessing a global variable, access must be protected. Pthreads provide a simple, primitive synchronization variable called a mutex. It provides a single, absolute owner of a section of code (the critical section) that is bracketed between calls to pthread_mutex_lock() and pthread_mutex_unlock() (see Hints below for details). The first thread that locks the mutex gets ownership, and any subsequent attempts to lock it will fail, causing the calling thread to go to sleep. When the owner unlocks, it, one of the sleeping threads will be awakened, made runnable and given the chance to obtain ownership of the mutex.


You will use the same socket code wrappers for this project as you did for project 3 to allow for client-server communication.

You will use the Pthreads library for your threading. (Note, gcc was only recently compiled to support pthread code. So, you may consider using cc, the native Compaq compiler, to build your project.) See the server.c and client.c samples for examples of how to make a basic server and client threaded.

You will need a #include < pthread.h > in your source code and -lpthread as an option to the linker to use pthreads. See the below Makefile below for a sample.

Do a man on any of the below calls for more information:

Warning! Some library functions are not thread safe because they use global or static variables, as discussed in class. strtok() is one of them. Read the man page to see if such system calls are thread safe. Often, there is a thread safe version, such as strtok_r().


Since you will be maintaining two source code programs for this project (the client and the threaded server), as well as the socket wrappers, you will want a Makefile. Here is a sample:

# makefile for threaded client-server (using pthreads)

LIB = -lpthread
CC = cc

all: server client

server: server.c sock.o
	$(CC) -o server server.c sock.o $(LIB)

client: client.c sock.o
	$(CC) -o client client .c sock.o $(LIB)

sock.o: sock.c sock.h
	$(CC) -c sock.c

	/bin/rm -f client server core *.o *~

See the man page for make for additional information on how to use makefiles.


You are to experimentally measure some performance parameters for your threaded server versus multiple-process. Specifically, you will use getrusage() to measure:

The easiest way of doing this is to have each child process (in the forked server) print out getrusage() statistics for itself. The system call getrusage() returns some process statistics that are kept by the operating system. See count.c for a sample of how to use getrusage() and do a man getrusage() for more information. For your project, you may print the statistical information to a file or just capture it from standard output. You can then analyze the data by adding the values across all children.

For the thread based server, you do not need to gather data for all the children and then add it. Instead, you just have the main thread gather data about itself.

You should do multiple runs with an increasing number of clients, say at least 1, 2, 3 and 4. Fixing a certain number of clients, you should also varying the length of the client connections, say from 10 seconds up to 2 minutes.

After gathering the data, you must analyze it. Draw at least two graphs:

Each graph should show two lines, the threaded server performance and the forked() server performance. The graph should have a title, and the axes should be clearly labled with the units. You should also compute average values for each of the statistics gathered above. Draw conclusions on what you see in the graphs. In particular, you must explain any results that result in conclusions you draw up given your data.

You might use gnuplot to generate your graphs. Gnuplot is an interactive plotting program. Do a man gnuplot for more information. Gnuplot has an online help in it's shell, too. Just type "help".

Hand In

Be sure to turn in all code needed to compile your program, including the socket wrappers, Makefile and client code. Make sure you have the names and login ids for all group members. In addition, turn in the code you used to do your performance evaluation along with your performance writeup. You may turn in your graphs electronically as long as they are in postscript, excel or some other format that I can read. Please compress your files before turning them in.

Return to 3013 Home Page

Send all questions to the TA mailing list.