Objective
This article will be divided into two parts, the first part of the implementation of a pair of concurrent back-up Server/client program (see the previous article in this part can not see the repetition); The second part is the server to add a zombie subprocess automatic cleanup mechanism.
So how does the server implement concurrency? How can there be a zombie process? What is a zombie process? How to deal with these zombie processes ... This article will give you one by one doubts.
Back up concurrent servers
function : Receive the data sent by the user and then send back to the user, and can process multiple user requests at the same time.
General Idea : Whenever a user request is received, the server fork a child process, allowing the child process to process the customer request.
Implementation Code :
1#include"Unp.h"2 3 int4MainintargcChar**argv)5 {6 intlistenfd, CONNFD;7 pid_t childpid;8 socklen_t Clilen;9 structsockaddr_in cliaddr, servaddr;Ten OneLISTENFD = Socket (Af_inet, Sock_stream,0); A -Bzero (&SERVADDR,sizeof(SERVADDR)); -servaddr.sin_family =af_inet; theSERVADDR.SIN_ADDR.S_ADDR =htonl (inaddr_any); -Servaddr.sin_port =htons (serv_port); - -Bind (LISTENFD, (SA *) &servaddr,sizeof(SERVADDR)); + - Listen (LISTENFD, Listenq); + A for ( ; ; ) { atClilen =sizeof(CLIADDR); -CONNFD = Accept (LISTENFD, (SA *) &cliaddr, &Clilen); - - /* - * Child Process Code - */ in if((Childpid = Fork ()) = =0) { - //turn off the listener socket first after the child process starts to Close (LISTENFD); + //back-firing processing - Str_echo (CONNFD); the //Exit Child Process *Exit0); $ }Panax Notoginseng //Close Connection Sockets - Close (CONNFD); the } +}
1#include"Unp.h"2 3 void4Str_echo (intsockfd)5 {6 ssize_t N;7 CharBuf[maxline];8 9 again:Ten while((n = Read (SOCKFD, buf, MAXLINE)) >0) One writen (SOCKFD, buf, n); A - if(N <0&& errno = =eintr) - Gotoagain; the Else if(N <0) -Err_sys ("Str_echo:read Error"); -}
echo Concurrent Client
function : Send data to the server, receive the information that the server reflects back and print.
General Idea : a little.
Implementation Code :
1#include"Unp.h"2 3 int4MainintargcChar**argv)5 {6 intsockfd;7 structsockaddr_in servaddr;8 9 if(ARGC! =2)TenErr_quit ("usage:tcpcli <IPaddress>"); One ASOCKFD = Socket (Af_inet, Sock_stream,0); - -Bzero (&SERVADDR,sizeof(SERVADDR)); theservaddr.sin_family =af_inet; -Servaddr.sin_port =htons (serv_port); -Inet_pton (Af_inet, argv[1], &servaddr.sin_addr); - +Connect (SOCKFD, (SA *) &servaddr,sizeof(SERVADDR)); - +STR_CLI (stdin, SOCKFD);//communicating with the server A atExit0); -}
1#include"Unp.h"2 3 void4Str_echo (intsockfd)5 {6 ssize_t N;7 CharBuf[maxline];8 9 again:Ten while((n = Read (SOCKFD, buf, MAXLINE)) >0) One writen (SOCKFD, buf, n); A - if(N <0&& errno = =eintr) - Gotoagain; the Else if(N <0) -Err_sys ("Str_echo:read Error"); -}
Run Tests
1. Start the server with Superuser privileges in one terminal
2. Open the client at another terminal and enter the IP address parameter 127.0.0.1
3. Perform the back-firing test, running as follows (several client terminals are operating normally):
Problem finding
It looks like this concurrent back-firing program is ready. But, unfortunately, it's not. Our next observation will lead us to the real topic of this article: the zombie subprocess .
First exit these client terminals. According to our initial assumptions, these sub-processes should have ended. But is this really true? We perform the following command at the terminal to view:
Figure, the stat display represents the status of the process, and z+ indicates that the process is in a "zombie" state. By comparison with its PID and ppid it is not difficult to find that the process of processing clients in the server does not "die", but instead become "zombies".
What is a zombie process
A zombie process is a process that has been withdrawn but still occupies resources.
Why do we have a zombie process?
The purpose of setting the zombie state is to maintain the information of the child process . The parent process sometimes needs to get information about some of the child processes that have been revoked.
How to handle zombie processes
For the zombie process in this case, of course we have to clean it up and release the resources it occupies.
12th article: The implementation of the concurrent back-up server and the cleanup of the zombie subprocess (on)