150 likes | 339 Views
Programming with TCP – III . Zombie Processes Cleaning Zombie Processes Concurrent Servers Using Threads pthread Library Functions TCP Socket Options. Zombie Processes . What is a zombie process?
E N D
Programming with TCP – III ZombieProcesses CleaningZombieProcesses ConcurrentServers Using Threads pthreadLibrary Functions TCP SocketOptions
Zombie Processes What is a zombie process? • Let’s follow through the steps involved in the normal termination of ourTcpEchoClient& TcpConcurrentEchoServer1. • Client exits (usertypes ‘quit’). • Client processclosesitssocketdescriptorbycallingclose. ThissendsFINtotheserver’send of the TCP toclosethesocket. • Theserver’schildprocess’ recv(read) returns0andclosesitsownend of theconnectionbycallingclose.
Zombie Processescont. • Whathappensnext? • Theserver’schildprocessterminatesbycallingexit. • A SIGCHLDsignal is deliveredtotheparentwhenthe server childterminates. • Thisoccurs in ourexample, but we do not catchthesignal in ourcodeandthedefaultactionthesignal is to be ignored. Thusthechildentersthezombiestate.
Zombie Processescont. • What is thepurpose of zombiestates? • Tomaintaininformationaboutthechild, fortheparenttofetch at some time later. • ThisinformationincludesprocessIDof thechild, itsterminationstatusandinformation on theresourceutilization of thechild (CPU time, memory, etc.)
Zombie Processescont. • What is the purpose of zombie states? • If a parent terminates and that parent has children in the zombie state, the parent process IDof all the zombie children is set to 1 (the initprocess) which will inherit the children and clean them up (i.e., initwill 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?
CleaningZombie Processes • How tocleanzombieprocesses? • Theparent (the main server) establishes a signalhandlertoreceiveSIGCHLDsignals. • Withinthesignalhandler, theparentcallswaitorwaitpidtogetthestatus of thechildprocess, whichremovesthechildprocessfromthekernel.
ExampleSignalHandler • Here is an examplesignalhandler: • 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(intsigno){ pid_tpid; intsigno; while((pid=waitpid(-1, &stat, WNOHANG))>0) printf(" Child %d terminated\n", pid); return; }
Main Loop of the Server 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); } • TcpConcurrentEchoServer2.c
ConcurrentServers Using Threads • Here is theoutline of a typicalconcurrent server usingthreads • ThreadCreation.c, TcpConcurrentEchoServer3.c void * doit(void *arg){ memcpy(connfd, arg, 4); functionto be ... executedbya close(connfd); workerthread } listenfd = socket(...); bind(listenfd, ...); listen(listenfd, ...); while(1){ connfd = accept(listenfd, ...); pthread_create(..., NULL, doit, &connfd); }
ConcurrentServers Using Threads main threadworkerthreads listenfd connfd User Kernel 0 1 2 3 4 5 6 7 8 9 Server’s PCB Socket Data Structure Socket Data Structure refcount = 1 TCP Buffers ... refcount = 1 TCP Buffers ... Forlistenfd Forconnfd
OtherpthreadLibrary Functions #include <pthread.h> • pthread_createfork • pthread_joinwaitpid • pthread_tpthread_self(void); getpid • Returnsthread ID of thecallingthread • intpthread_detach(pthread_ttid); • Returns0ifOK, positiveExxxvalue on error. • A thread is joinable (default) ordetached. When a joinablethreadterminates, itsthreadIDandexitstatusareretaineduntilanotherthreadcallspthread_join. But a detachedthread is like a daemonprocess: When it terminates, allitsresourcesarereleasedandwecannotwaitfor it toterminate. Ifonethreadneedstoknowwhenanotherthreadterminates, it is besttoleavethethread as joinable. Otherwise, makethethreaddetached. • Thisfunction is commonlycalledbythethreadthatwantstodetach it self: pthread_detach(pthread_self());
OtherpthreadLibrary Functions #include <pthread.h> • voidpthread_exit(void *status); • Onewayfor a threadtoexit is tocallthisfunction. • Ifthethread is not detached, itsthreadIDandexitstatusareretainedfor a laterpthread_joinbysomeotherthread in thecallingprocess. • Thepointer «status»must NOT pointto a localobject (i.e., a localvariablestored in stack) as theobjectdisappearswhenthethreadterminates.
OtherpthreadLibrary Functions #include <pthread.h> voidpthread_exit(void *status); • Thereare 2 otherwaysfor a threadtoterminate. • Thefunctionthatstartedthethreadreturns. Since thatfunctionmust be declaredtoreturn a pointertovoid, thatreturnvalue is theexitstatusthethread. • The main thread of theprocessterminatesorifanyotherthreadcallsEXITtoterminatetheprocess, whichterminates ALL threads.
TCP SocketOptions • TCP_MAXSEG • Allowstofetchor set theMSSfor a TCP connection. • TCP_NODELAY • If set, thisoptiondisablesTCP’sNagleAlgorithm. Bydefaultthisalgorithm is enabled. Recallthatthepurpose of theNagleAlgorithm is toreducethenumber of smallpackets on the network. • Thedefinition of smallpacket is anypacketsmallerthanMSS. • Thealgorithmstatesthatif TCP has outstanding data (i.e., data thatour TCP has sent, andforwhich it is currentlyawaiting an ACK), thennosmallpacketswill be sent on theconnection in responseto a userwriteuntiltheexisting data is ACKed. • TwocommonappsthatsufferfromNagle’salgorithmarerlogin& telnet, since theysendeachkeystroke as a separatepacket.
Telnet ExampleforNagle’sAlgorithm Here is how a telnet sessionwillbehavewith/withoutNaglealgorithm: (Assume an RTT of 600 ms & usertypes a charevery 250 ms) NagleEnabled (default) NagleDisabled H 0 H 0 H E 250 E 250 L 500 L 500 600 EL L 750 L 750 O 1000 O 1000 1200 ! 1250 LO ! 1250 1500 1750 1800 ! 1850 2000 WithNagleDisabledeverycharwill be in a packet. 2250 • TcpOptions.c 2400