18.3 Connection-Oriented Server Strategies

Team-FLY

Once a server receives a request, it can use a number of different strategies for handling the request. The serial server depicted in Figure 18.2 completely handles one request before accepting additional requests .

Example 18.2

The following pseudocode illustrates the serial-server strategy.

 for ( ; ; ) {    wait for a client request on the listening file descriptor    create a private two-way communication channel to the client    while (no error on the private communication channel)       read from the client       process the request       respond to the client    close the file descriptor for the private communication channel } 

A busy server handling long-lived requests such as file transfers cannot use a serial-server strategy that processes only one request at a time. A parent server forks a child process to handle the actual service to the client, freeing the server to listen for additional requests. Figure 18.4 depicts the parent-server strategy. The strategy is ideal for services such as file transfers, which take a relatively long time and involve a lot of blocking.

Figure 18.4. A parent server forks a child to handle the client request.

graphics/18fig04.gif

Example 18.3

The following pseudocode illustrates the parent-server strategy.

 for( ; ; ) {    wait for a client request on the listening file descriptor    create a private two-way communication channel to the client    fork a child to handle the client    close file descriptor for the private communication channel    clean up zombie children } 

The child process does the following.

 close the listening file descriptor handle the client close the communication for the private channel exit 

Since the server's child handles the actual service in the parent-server strategy, the server can accept multiple client requests in rapid succession. The strategy is analogous to the old-fashioned switchboard at some hotels. A client calls the main number at the hotel (the connection request). The switchboard operator (server) answers the call, patches the connection to the appropriate room (the server child), steps out of the conversation, and resumes listening for additional calls.

Exercise 18.4

What happens in Example 18.3 if the parent does not close the file descriptor corresponding to the private communication channel?

Answer:

In this case, both the server parent and the server child have open file descriptors to the private communication channel. When the server child closes the communication channel, the client will not be able to detect end-of-file because a remote process (the server parent) still has it open . Also, if the server runs for a long time with many client requests, it will eventually run out of file descriptors.

Exercise 18.5

What is a zombie child? What happens in Example 18.3 if the server parent does not periodically wait for its zombie children?

Answer:

A zombie is a process that has completed execution but has not been waited for by its parent. Zombie processes do not release all their resources, so eventually the system may run out of some critical resource such as memory or process IDs.

The threaded server depicted in Figure 18.5 is a low-overhead alternative to the parent server. Instead of forking a child to handle the request, the server creates a thread in its own process space. Threaded servers can be very efficient, particularly for small or I/O intensive requests. A drawback of the threaded-server strategy is possible interference among multiple requests due to the shared address space. For computationally intensive services, the additional threads may reduce the efficiency of or block the main server thread. Per-process limits on the number of open file descriptors may also restrict the number of simultaneous client requests that can be handled by the server.

Figure 18.5. A threaded server creates threads to handle client requests.

graphics/18fig05.gif

Example 18.6

The following pseudocode illustrates the threaded-server strategy.

 for ( ; ; ) {     wait for a client request on the listening file descriptor     create a private two-way communication channel to the client     create a detached thread to handle the client } 
Exercise 18.7

What is the purpose of creating a detached (as opposed to attached) thread in Example 18.6?

Answer:

Detached threads release all their resources when they exit, hence the main thread doesn't have to wait for them. The waitpid function with the NOHANG option allows a process to wait for completed children without blocking. There is no similar option for the pthread_join function.

Exercise 18.8

What would happen if the main thread closed the communication file descriptor after creating the thread to handle the communication?

Answer:

The main thread and child threads execute in the same process environment and share the same file descriptors. If the main thread closes the communication file descriptor, the newly created thread cannot access it. Compare this situation to that encountered in the parent server of Example 18.3, in which the child process receives a copy of the file descriptor table and executes in a different address space.

Other strategies are possible. For example, the server could create a fixed number of child processes when it starts and each child could wait for a connection request. This approach allows a fixed number of simultaneous parallel connections and saves the overhead of creating a new process each time a connection request arrives. Similarly, another threading strategy has a main thread that creates a pool of worker threads that each wait for connection requests. Alternatively, the main thread can wait for connection requests and distribute communication file descriptors to free worker threads. Chapter 22 outlines a project to compare the performance of different server strategies.

Team-FLY


Unix Systems Programming
UNIX Systems Programming: Communication, Concurrency and Threads
ISBN: 0130424110
EAN: 2147483647
Year: 2003
Pages: 274

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net