When a process terminates normally or abnormally, the kernel sends a SIGCHLD signal to its parent process. Because the sub-process termination is an asynchronous event (which can occur at any time when the parent process runs), this signal is also an asynchronous notification sent by the kernel to the parent process. The parent process can choose to ignore the signal, or provide a function (Signal Processing Program) that is called when the signal occurs ). The default action for this signal is to ignore it ).
The process that calls wait or waitpid may occur:
- If all its sub-processes are still running, it will be blocked.
- If a child process has been terminated and is waiting for the parent process to obtain its termination status, the child process will be terminated and returned immediately.
- If it does not have any sub-process, an error is returned immediately.
If the process calls wait because it receives the SIGCHLD signal, it is expected that wait will return immediately. However, if wait is called at any time, the process may be blocked.
# Include <sys/wait. h> *-* statloc,-. If the WNOHANG option is specified and the sub-process status specified by pid is not changed, 0 is returned.
The differences between these two functions are as follows:
- Before a sub-process is terminated, wait blocks its callers, while waitpid has an option to prevent callers from blocking.
- Waitpid does not wait for the first child process after its call. It has several options to control the process it waits.
If a child process has been terminated and is a dead process, wait immediately returns and obtains the state of the child process. Otherwise, wait blocks the caller until the child process is terminated. If the caller is blocked and has multiple sub-processes, wait returns immediately when one sub-process is terminated. Because wait returns the process ID of the final sub-process, it always knows which sub-process is terminated.
The statloc parameter of these two functions is an integer pointer. If statloc is not a null pointer, the termination state of the terminated process is stored in the unit to which it points. If you do not care about the termination status, you can specify this parameter as a null pointer.
Traditionally, the status characters returned by these two functions are defined by the implementation. Some BITs indicate the exit status (normal return), others indicate the signal number (abnormal return), and one indicate whether a core file is generated. POSIX.1 specifies the status to be viewed by the macros defined in <sys/wait. h>. There are four mutex macros that can be used to obtain the cause of Process Termination. Their names start with WIF. Based on which of the four macros is true, you can use another macro (the macro marked by an underline in the 8-1 table) to obtain the termination status, signal number, and so on. The four mutex macros are shown in Table 8-1.
Table 8-1 macro used to check the termination status returned by wait and waitpid
| Macro |
Description |
| WIFEXITED (status) |
If the returned status is normal, it is true. This can be executed.WEXITSTATUS (status ),Take the low 8-bit value that the sub-process sends to the exit, _ exit, or _ Exit parameters. |
| WIFSIGNALED (status) |
If the returned status is abnormal, the sub-process returns true (receive a non-capturing signal ). In this case, executeWTERMSIG (status ),Obtains the signal number that causes the sub-process to terminate. In addition, some implementations define macrosWCOREDUMP (status). If the core file of the terminated process has been generated, it returns the true |
| WIFSTOPPED (status) |
If the status is returned for the current pause sub-process, it is true. In this case, executeWSTOPSIG (status ),Obtains the signal number used to suspend the sub-process. |
| WIFCONTINUED (status) |
If the child process that has been resumed after the job control is suspended returns the status, it is true. (POSIX.1 XSI extension; only used for waitpid .) |
Program list 8-3 Print description of exit status
[root@localhost apue]# cat prog8-<sys/wait.h> ? :
Program listing 8-4 demonstrate different exit values (call the pr_exit function in the prog8-3)
[root@localhost apue]# cat prog8-<sys/wait.h> ((pid = fork()) < (pid == ); (wait(&status) != pid) ((pid = fork()) < (pid == ) (wait(&status) != pid) ((pid = fork()) < (pid == ) /= ; (wait(&status) != pid)
Run this program:
[root@localhost apue]# ./prog8-= = =
Unfortunately, there is no portable way to map the signal numbers obtained by WTERMSIG to descriptive names. We must check the <signal. h> header file to know that the value of SIGABRT is 6, and the value of SIGFPE is 8.
As described above, if a process has several sub-processes, wait will return if one sub-process is terminated.What should I do if I want to wait for a specified process to terminate (if I know that I want to wait for the process ID?POSIX.1 defines the waitpid function to provide this function (and some other functions ).
ForPid Parameters in the waitpid FunctionThe functions are as follows:
| Pid =-1 |
Wait for any sub-process. In this respect, waitpid is equivalent to wait. |
| Pid> 0 |
Wait for the child process whose process ID is equal to the pid. |
| Pid = 0 |
Wait for any sub-process whose group ID is equal to the called process group ID. |
| Pid <-1 |
Wait for any sub-process whose group ID is equal to the absolute value of pid. |
The waitpid function returns the process ID of the final sub-process and stores the termination status of the sub-process in the storage unit pointed by the status. For wait, the only error is that the calling process has no sub-process (when a function call is interrupted by a signal, another error may be returned ). However, for waitpid, if the specified process or process group does not exist, or the process specified by the pid parameter is not a sub-process that calls the process, an error will occur.
Options ParametersThis allows us to further control the waitpid operation. This parameter can be 0, or the result of the constant bitwise "or" Operation in Table 8-2.
Table 8-2 options constant of waitpid
| Constant |
Description |
| WCONTINUED |
If Job control is supported, any sub-process specified by the pid will continue after the pause, but its status has not been reported, and its status will be returned. |
| WNOHANG |
If the child process specified by the pid is not immediately available, the waitpid is not blocked, and the returned value is 0. |
| WUNTRACED |
If an implementation supports job control, and any sub-process specified by the pid is in the paused state, and its status has not been reported since the pause, the status is returned. The WIFSTOPPED macro determines whether the returned value corresponds to a paused sub-process. |
The waitpid function provides three functions not provided by the wait function:
(1) waitpid can wait for a specific process, while wait returns the status of any final child process.
(2) waitpid provides a non-blocking version of wait. Sometimes you want to get the status of a sub-process, but do not want to block it.
(3) waitpid supports job control (using the WUNTRACED and WCONTINUED options ).
If a process fork a sub-process, but do not wait for the sub-process to terminate, do not want the sub-process to be frozen until the parent process ends, the technique to achieve this requirement is to call fork twice.
Program list 8-5 call fork twice to avoid zombie Process
[root@localhost apue]# cat prog8-<sys/wait.h> ((pid = fork()) < (pid == ) ((pid = fork()) < (pid > ); (waitpid(pid, NULL, ) != pid)
The second child process calls sleep to ensure that the first child process is terminated when the parent process ID is printed. After fork, the Parent and Child processes can continue to execute, and we cannot predict which one will be executed first. After fork, if the second child process is not sleep, it may be executed first than its parent process, so the parent process ID printed by it will be the parent process that created it, instead of the init process (process ID 1 ).
Execution result:
[root@localhost apue]# ./prog8-=
Note: When the original process (that is, the exec process) terminates, shell prints its prompt, which is before the second child process prints its parent process ID.
This blog is excerpted from advanced programming for UNIX environments (version 2) and used only for personal learning records. For more information about this book, see:Http://www.apuebook.com/.