c++笔记(等待子进程退出函数)

在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等。但是仍然为其保留一定信息,这些信息主要是指进程控制模块PCB的信息(包括进程号,退出状态,运行时间等)

父进程可以通过调用wait或waitpid得到它的退出状态同时彻底清除掉这个进程

wait()和waitpid()函数功能一样,区别在于 wait()函数会阻塞,waitpid()可以设置不阻塞,waitpid()还可以指定等待哪个子进程结束。

一次wait或waitpid调用只能清理一个子进程,清理多个子进程要用循环语句

#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int *status);
// 功能   等待任意一个子进程结束 如果任意一个子进程结束了,此函数会回收该子进程的资源
// 参数   status  进程退出时的状态信息
// 返回值  成功  己结束子进程的进程号     失败 -1

调用wait()函数的进程会挂起(阻塞),直到它的一个子进程退出或收到一个不能被忽视的信号时才被唤醒

若调用进程没有子进程,该函数立即返回,若它的子进程己结束,该函数同样会立即返回,并且会回收那个早己结束进程的资源

所以 wait() 函数的主要功能为回收己经结束子进程的资源

如果 status 的参数不是 NULL, wait()就会把子进程退出时的状态取出并存入其中,这是一个整形值,指出了子进程是正常退出还是被非正常结束的

这个退出信息在一个int 中包含了多个字段,直接使用这个值没有意义,我们需要用宏定义取出其中的每个字段


宏函数分为如下三组

WIFEXITED(status) 非0时 表正常退出

可用 WEXITSTTATUS(status) 获取退出状态(exit的参数)


WIFSIGNALED(status) 非0时 表异常退出

可用 WTERMSIG(status) 获取使进程终止的那个信号编号


WIFSTOPPED(status) 非0时 表进程处于暂停状态

WSTOPSIG(status) 获取使进程暂停的那个信号编号

WIFCONTINUED(status) 进程暂停后己经续运行


// wait.c
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
int main(){
	int status=0;
	int i=0;
	int ret=-1;
	pid_t pid=-1;
	pid=fork();
	//子进程执行
	if(0==pid){
		for(i=0;i<10;i++){
			printf("fork pid	%d	%d\n",getpid(),i+1);
			sleep(2);
		//子进程退出
		exit(10);
	printf("main wait fork exit\n");
	//父进程阻塞 等待子进程退出
	ret = wait(&status);
	if(-1 == ret){
		perror("wait");
		return 1;
	printf("fork exit success;recovery fork resource success\n");
	if(WIFEXITED(status)){
		printf("fork exit success status code is %d\n",WEXITSTATUS(status));
	}else if(WIFSIGNALED(status)){
		printf("fork was killed by %d\n",WTERMSIG(status));
	}else if(WIFSTOPPED(status)){
		printf("fork was stop by %d\n",WSTOPSIG(status));
	return 0;	
// 编译 gcc wait.c -o wait
// 正常运行 结果如图一
// 再次运行 开一个终端 kill 7203  结果如图二
// 再次运行 开一个终端 kil -19 7234  结果如图三 然后 kill -18 7234 会继续向下执行
//


图一


图二


图三,被暂停



waitpid函数

#include<sys/types.h>
#include<sys/wait.h>
pid_t waitpid(pid_t pid,int *status,int options);
功能    等待子进程终止 如果子进程终止了 此函数会回收子进程资源
参数    pid > 0 等待进程ID等于pid 的子进程
        pid = 0 等待同一个进程组中的任何子进程,如果子进程己经加入了别的进程组,waitpid 不会等待
        pid = -1 等待任一子进程,此时 waitpid 和 wait 作用一样
        pid < -1 等待指定进程组组中的任何子进程,这个进程组的ID等于 pid 的绝对值
        status  进程退出时的状态信息 和 wait() 用法一样
        options  options 提供了一些额外的选项来控制 waitpid()
                 0 同 wait() 阻塞父进程 等待子进程退出
                 WNOHANG 没有任何己经结束的子进程,则立即返回
                 WUNTRACE 如果子进程暂停了则此函数马上返回,并且不予理会子进程的结束状态 
返回值  当正常返回时 waitpid() 返回收集到的己经回收子进程的进程号
        如果设置了选项 WNOHANG 而调用中 waitpid() 发现没有己退出的子进程可等待 则返回0;