15
Programming with TCP – III 1. Zombie Processes 2. Cleaning Zombie Processes 3. Concurrent Servers Using Threads pthread Library Functions 4. TCP Socket Options

Programming with TCP – III 1. Zombie Processes 2. Cleaning Zombie Processes 3. Concurrent Servers Using Threads pthread Library Functions 4. TCP Socket

Embed Size (px)

Citation preview

Page 1: Programming with TCP – III 1. Zombie Processes 2. Cleaning Zombie Processes 3. Concurrent Servers Using Threads  pthread Library Functions 4. TCP Socket

Programming with TCP – III

1. Zombie Processes2. Cleaning Zombie Processes3. Concurrent Servers Using Threads pthread Library Functions

4. TCP Socket Options

Page 2: Programming with TCP – III 1. Zombie Processes 2. Cleaning Zombie Processes 3. Concurrent Servers Using Threads  pthread Library Functions 4. TCP Socket

Zombie Processes

What is a zombie process? Let’s follow through the steps involved in

the normal termination of our TcpEchoClient & TcpConcurrentEchoServer1.1. Client exits (user types ‘quit’).2. Client process closes its socket

descriptor by calling close. This sends FIN to the server’s end of the TCP to close the socket.

3. The server’s child process’ recv (read) returns 0 and closes its own end of the connection by calling close.

Page 3: Programming with TCP – III 1. Zombie Processes 2. Cleaning Zombie Processes 3. Concurrent Servers Using Threads  pthread Library Functions 4. TCP Socket

Zombie Processes cont. What happens next?

4. The server’s child process terminates by calling exit.

5. A SIGCHLD signal is delivered to the parent when the server child terminates.

This occurs in our example, but we do not catch the signal in our code and the default action the signal is to be ignored. Thus the child enters the zombie state.

Page 4: Programming with TCP – III 1. Zombie Processes 2. Cleaning Zombie Processes 3. Concurrent Servers Using Threads  pthread Library Functions 4. TCP Socket

Zombie Processes cont. What is the purpose of zombie

states? To maintain information about the

child, for the parent to fetch at some time later.

This information includes processID of the child, its termination status and information on the resource utilization of the child (CPU time, memory, etc.)

Page 5: Programming with TCP – III 1. Zombie Processes 2. Cleaning Zombie Processes 3. Concurrent Servers Using Threads  pthread Library Functions 4. TCP Socket

Zombie Processes cont. What is the purpose of zombie states? If a parent terminates and that parent

has children in the zombie state, the parent process ID of all the zombie children is set to 1 (the init process) which will inherit the children and clean them up (i.e., init will wait for them which removes the zombie)

Obviously we do not want to leave zombies around. So whenever we fork a child, we must wait for it to prevent them from becoming zombies.

How?

Page 6: Programming with TCP – III 1. Zombie Processes 2. Cleaning Zombie Processes 3. Concurrent Servers Using Threads  pthread Library Functions 4. TCP Socket

Cleaning Zombie Processes How to clean zombie processes?

The parent (the main server) establishes a signal handler to receive SIGCHLD signals.

Within the signal handler, the parent calls wait or waitpid to get the status of the child process, which removes the child process from the kernel.

Page 7: Programming with TCP – III 1. Zombie Processes 2. Cleaning Zombie Processes 3. Concurrent Servers Using Threads  pthread Library Functions 4. TCP Socket

Example Signal Handler Here is an example signal handler:

Recall that delivery of a signal interrupts a system call (e.g. signal). So the main loop of the server must be rewritten accordingly.

void sig_chld(int signo){ pid_t pid; int signo;

while((pid=waitpid(-1, &stat, WNOHANG))>0) printf(" Child %d terminated\n", pid); return;}

Page 8: Programming with TCP – III 1. Zombie Processes 2. Cleaning Zombie Processes 3. Concurrent Servers Using Threads  pthread Library Functions 4. TCP Socket

Main Loop of the Server

TcpConcurrentEchoServer2.c

while(1){ connfd = accept(listenfd, ...); if(connfd<0){ if(errno == EINTR) continue; else{ perror("accept"); exit(1); } } if(fork()==0){ close(listenfd); doit(connfd); exit(0); } close(connfd);}

Page 9: Programming with TCP – III 1. Zombie Processes 2. Cleaning Zombie Processes 3. Concurrent Servers Using Threads  pthread Library Functions 4. TCP Socket

Concurrent Servers Using Threads Here is the outline of a typical

concurrent server using threads

ThreadCreation.c, TcpConcurrentEchoServer3.c

void * doit(void *arg){ memcpy(connfd, arg, 4); function to be ... executed by a close(connfd); worker thread}

listenfd = socket(...);bind(listenfd, ...);listen(listenfd, ...);while(1){ connfd = accept(listenfd, ...); pthread_create(..., NULL, doit, &connfd);}

Page 10: Programming with TCP – III 1. Zombie Processes 2. Cleaning Zombie Processes 3. Concurrent Servers Using Threads  pthread Library Functions 4. TCP Socket

Concurrent Servers Using Threads

main thread worker threads

User

Kernel

0 1 2 3 4 5 6 7 8 9

ref count = 1TCP Buffers ...

For listenfd

ref count = 1TCP Buffers ...

For connfd

listenfd connfd

Server’s PCB

Socket Data Structure

Socket Data Structure

Page 11: Programming with TCP – III 1. Zombie Processes 2. Cleaning Zombie Processes 3. Concurrent Servers Using Threads  pthread Library Functions 4. TCP Socket

1. pthread_create fork2. pthread_join waitpid3. pthread_t pthread_self(void); getpid

◦ Returns thread ID of the calling thread

4. int pthread_detach(pthread_t tid);◦ Returns 0 if OK, positive Exxx value on error.◦ A thread is joinable (default) or detached. When a

joinable thread terminates, its threadID and exit status are retained until another thread calls pthread_join. But a detached thread is like a daemon process: When it terminates, all its resources are released and we cannot wait for it to terminate. If one thread needs to know when another thread terminates, it is best to leave the thread as joinable. Otherwise, make the thread detached.

◦ This function is commonly called by the thread that wants to detach it self: pthread_detach(pthread_self());

Other pthread Library Functions#include <pthread.h>

Page 12: Programming with TCP – III 1. Zombie Processes 2. Cleaning Zombie Processes 3. Concurrent Servers Using Threads  pthread Library Functions 4. TCP Socket

5. void pthread_exit(void *status);◦ One way for a thread to exit is to call this function.◦ If the thread is not detached, its threadID and exit

status are retained for a later pthread_join by some other thread in the calling process.

◦ The pointer «status» must NOT point to a local object (i.e., a local variable stored in stack) as the object disappears when the thread terminates.

Other pthread Library Functions#include <pthread.h>

Page 13: Programming with TCP – III 1. Zombie Processes 2. Cleaning Zombie Processes 3. Concurrent Servers Using Threads  pthread Library Functions 4. TCP Socket

void pthread_exit(void *status); There are 2 other ways for a thread to

terminate.

1. The function that started the thread returns. Since that function must be declared to return a pointer to void, that return value is the exit status the thread.

2. The main thread of the process terminates or if any other thread calls EXIT to terminate the process, which terminates ALL threads.

Other pthread Library Functions#include <pthread.h>

Page 14: Programming with TCP – III 1. Zombie Processes 2. Cleaning Zombie Processes 3. Concurrent Servers Using Threads  pthread Library Functions 4. TCP Socket

1. TCP_MAXSEG◦ Allows to fetch or set the MSS for a TCP connection.

2. TCP_NODELAY◦ If set, this option disables TCP’s Nagle Algorithm. By

default this algorithm is enabled. Recall that the purpose of the Nagle Algorithm is to reduce the number of small packets on the network.

◦ The definition of small packet is any packet smaller than MSS.

◦ The algorithm states that if TCP has outstanding data (i.e., data that our TCP has sent, and for which it is currently awaiting an ACK), then no small packets will be sent on the connection in response to a user write until the existing data is ACKed.

◦ Two common apps that suffer from Nagle’s algorithm are rlogin & telnet, since they send each keystroke as a separate packet.

TCP Socket Options

Page 15: Programming with TCP – III 1. Zombie Processes 2. Cleaning Zombie Processes 3. Concurrent Servers Using Threads  pthread Library Functions 4. TCP Socket

H 0

Telnet Example for Nagle’s AlgorithmHere is how a telnet session will behave with/without Nagle algorithm: (Assume an RTT of 600 ms & user types a char every 250 ms)

E 250L 500 L 750O 1000 ! 1250 1500 1750 2000 2250 2400

H

EL

LO

!

H 0E 250L 500 L 750O 1000 ! 1250

1850With Nagle Disabled

every char will be in a packet. TcpOptions.c

Nagle Enabled (default)

Nagle Disabled

600

1200

1800