I have already covered the process creation and some basic knowledge in the previous blog posts, and I will not dwell on the details of this blog post, I'll focus on the finalization of the process and the monitoring of the parent process's child process, as well as the function Group exec ()
1. Termination of the process (1) _exec () and exit ()
Process termination in two cases, one is to receive some kind of signal abnormal termination, the other is to call _exit () normal exit
#include<unistd.h>void _exit(int status);
The parameter status holds the terminating state of the process, and the parent process can call wait () to get the state
#include<stdio.h>void _exit(int status);
In general, the process does not call _exit () directly but calls exit (), and it does the following before calling _exit ()
Call the exit handler, which executes in the reverse order of registration
. Refreshing the stdio stream buffer
. Use the value provided by the status to execute the _exit () system call
Another way to terminate a program is to return from the main function (return), which is also called exit () the only difference is that if any function executed during the exit process wants to access the local variable of the main function, returning from the main function results in an undefined 1 behavior
(2) Details of the termination of the process
The following actions occur regardless of whether the process is terminated normally
. Close all open file descriptors, directory stream ...
Because the file descriptor is closed, all file locks held by the process are released.
If a process is a management process for a management terminal, it sends a sighup signal to all processes in that terminal process group
Any semaphore opened by the shutdown process.
(3) Exit the handler
#include<stdlib.h>int atexit(void(*func)(void));//返回0成功,否则失败
The function atexit () adds Func () to a list of functions, and all functions in the function list are called when the process terminates, and the function func should be defined as no return value and no arguments are accepted
2. Monitor sub-processes (1). System call Wait ()
#include<sys/wait.h>pid_t wait(int status);//返回退出子进程的ID
The call blocks the parent process from waiting for the child process to terminate and returns the terminating state of the child process in the buffer to which the status is pointing, and wait () performs the following actions:
If the calling process is not terminated by a child process that was not previously awaited, the call will be blocked until a child process terminates and returns immediately if a child process has terminated at the time of the call
If status is not NULL, then information about how the child process terminates is returned by the entire variable that the status points to.
The kernel will append the process CPU time and the resource usage data to the total running of all child processes under the parent process
The PID of the terminating child process as the return result of wait
(2) system call Waitpid ()
#include<sys/wait.h>pid_t waitpid(pid_t pid,int *status,int options);//返回子进程ID
Waitpid () compared to the place where wait () was breached
If the PID is greater than 0, the child process that waits for the process ID to be PID
. If the PID equals 0, wait for all child processes in the same process group as the calling process
If the PID is less than-1, it waits for the process group identifier to equal the PID absolute value of the child process
If the PID equals-1, wait for any child process
Parameter options is a bitmask that can contain 0 or more of the following flags
Options |
Specific Description |
wuntraced |
Returns information about terminating a child process and also returning child process information that is stopped by a signal |
wcontinued |
Returns the status information for a stopped subprocess that was resumed after receiving a Sigcont (pause restart) signal |
Wnohang |
If the child process specified by the parameter PID does not change state, it returns immediately without blocking |
(3) Wait3 () and WAIT4 ()
#include<sys/resource.h>#include<sys/wait.h>pid_t wait3(int *status,int option,struct rusage *rusage);pid_t wait4(pid_t pid,int *status,int options,struct rusage *rusage);
The fundamental difference between wait3 and WAIT4 is that they return the resource usage of the child process through the rusage structure
(4) Orphan process with zombie process orphan process:
当父进程先于子进程退出时,该子进程就变成了孤儿进程,该孤儿进程会被init收养在父进程执行wait()之前,其子进程就已终止,那么系统会将子进程转化为僵尸进程,来使父进程获得其终止状态,僵尸进程把自己把持的大部分资源都释放掉,只保留了内核进程表中的一条记录,其中包含该进程ID,终止状态,资源使用数据等信息,当父进程执行wait()后,内核将删除该僵尸进程,如果父进程未执行wait()随即退出,则init会接管该进程并调用wait()
(5). Signal SIGCHLD
When the child process terminates, the kernel sends a SIGCHLD signal to the parent process, ignoring the default processing of the signal, but we can install the signal handler to handle it to clean up the zombie process.
(6) Execution of procedures
#include<unistd.h>int execve(constchar *pathname,char *const argv[],char *const envp);//不返回则成功,-1则失败
The parameter pathname contains the pathname of the new program to be loaded into the current process space, and the parameter argv specifies the command-line arguments passed to the new program, and the parameter envp specifies the list of environments for the new program
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Summary of relevant knowledge of the process