First, the fork () function, step apue 8.3. A clearer explanation can refer to http://blog.csdn.net/lingdxuyan/article/details/4993883 and http://www.oschina.net/question/195301_62902
One thing to add is that when fork returns, the reference count for each file or set of interface descriptors in the original process is added by 1 (equivalent to being opened more than once), each time close is called, and the reference count minus 1, the socket is closed only if the reference count is reduced to 0 o'clock.
The only way executable files are executed by Linux is to call exec and replace the current process image with a new program file, starting with the program's main execution.
The typical Linux practice is to start exec after fork, usually with cow technology.
About the zombie process
When the process finishes at exit (), the process table retains information such as the process number, exit status, run time, and so on. Although it has given up memory space, it cannot be dispatched. Because Linux has a limited number of processes, too many zombie processes will take up the available process numbers, causing new processes to fail to spawn and must be purged in a timely manner. I was wondering ... What is the meaning of the zombie process? A: Preserve the status of the child process exit and determine the cause of death while waiting for the parent process to corpse. (Calling various macros in the parent process: wexitstatus (status), etc.)
Processing method:
1. The parent process calls wait () or waitpid () to the end of the child process, which causes the parent process to hang
2. If the parent process does not care when the child process ends, it can call signal (Sigchld,sig_ign) to notify the kernel that the kernel will be automatically reclaimed after the child process has finished. Note: This method is not portable and stevent mentioned in UNP5.9 that this processing is not a POSIX standard and is only available on some systems
3, also uses the asynchronous processing way, the signal processing function signal, installs the handler to process the SIGCHLD signal. In this way, the parent process can call wait () in handler to recycle. However, due to the same signal does not queue the reason, we should pay attention to processing the simultaneous submission of the signal, that is, the simultaneous termination of the sub-process processing. UNP5.10 discusses the problem in detail and gives a safe method.
4, by the signal processing function to set the SA_NOCLDWAIT flag. Do not create a zombie process when the child process of the calling process terminates (APUE10.14)
Signala.sa_handler = Sig_ign;signala.sa_flags = Sa_nocldwait;sigemptyset (&signala.sa_mask); Sigaction (SIGCHLD, &signala, NULL);
5, because of the characteristics of the process, after its parent process exits, the child process will be adoptive to the INIT process, if the child process is already a zombie process, init directly recycle it, because its manager parent process no longer exists, Init does not care about the cause of death. Therefore, you can take two consecutive fork (), the sub-process directly after the fork exit, by the sun process to process, after the end of the sun process, the resources are retrieved by Init. Note, however, that the cleanup of child processes is also done by the parent process.
Signal Processing:
In this summary, each core signal, the operating system has a default processing method, such as the previous SIGCHLD, default is ignored, so do not handle will leave zombies. We can define our own functions to handle the signals, noting that Sigkill and sigstop cannot be captured or ignored.
The signal processing function is process-dependent, common to all threads of the process.
In the signal processing function, try not to use a non-reentrant function such as printf (UNP11.18)
A signal is responded to by a signal processing function, which is masked during processing. The standard signal implementation does not have a queued function, so the signal may be lost, and multiple successive signals are too late to process. If a signal set is set through Sa_mask, the signal in the collection is also blocked.
The POSIX method for establishing a signal processing function is to call sigaction () and Simply call Signal (), although it is not a POSIX function, but most platforms use signal () to implement Sigaction () for backwards compatibility.
The following is a simple multi-process server-side program:
#include "simon_socket.h" #define Serv_port 12345extern pid_t waitpid (pid_t, int *, int), void handler (int signo) {pid_t pid ; int status;while (PID = Waitpid ( -1, &status, Wnohang) > 0) {printf ("Child process%d terminated\nthe wexitstatus Return code is%d \nthe wifexited return code is%d\n ", PID, Wexitstatus (status), wifexited (status));}} int main () {int sockfd, acfd;struct sockaddr_in client_addr;size_t sin_len = sizeof (CLIENT_ADDR); sockfd = Init_tcp_psock ( Serv_port); signal (SIGCHLD, handler);/* Another method: *struct sigaction signala;signala.sa_handler = Sig_ign;signala. Sa_flags = Sa_nocldwait;sigemptyset (&signala.sa_mask); Sigaction (SIGCHLD, &signala, NULL); */while (1) {if ( ACFD = Accept (SOCKFD, (struct sockaddr *) &client_addr, &sin_len)) = =-1) {perror ("Accept request failed:"); return 1;} elseprintf ("Get a connection from%s:%d!\n", Inet_ntoa (CLIENT_ADDR.SIN_ADDR), Ntohs (client_addr.sin_port));p id_t pid; if (PID = fork ()) > 0) {close (ACFD); continue;} else if (PID = = 0) {Close (SOCKFD);p rocess_client (ACFD, &CLIENT_ADDR); close (ACFD); exit (0);} Else{perror ("Fork error"); exit (0);}} Close (SOCKFD); return 0;}
The implementation of some calling functions in the code, my GITHUB:HTTPS://GITHUB.COM/SIMON-XIA/LNP