linux入门到精通-第十章-进程和程序(2)
目录
参考
等待子进程退出函数
概述
在每个进程退出的时候,内核释放该进程所有的资源、包括打开的文件、占用的内存等。但是仍然为其保留一定的信息,这些信息主要指进程控制块PCB的信息 (包括进程号、退出状态、运行时间等)。父进程可以通过调用wait或waitpid得到它的退出状态,同时彻底清除掉这个进程。wait() 和 waitpid() 函数的功能一样,区别在于wait() 函数会阻塞,waitpid()可以设置不阻塞,waitpid()还可以指定等待哪个子进程结束。
注意:一次wait或waitpid调用只能清理一个子程,清理多个子进程应使用循环
wait函数
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
功能:
等待任意一个子进程结束,如果任意一个子进程结束了,此函数会回收该子进程的资源.
参数:
status : 进程退出时的状态信息
返回值:
成功:已经结束子进程的进程号
失败:-1
调用 wait()函数的进程会挂起(阻塞),直到它的一个子进程退出或收到一个不能被忽视的信号时才被唤醒(相当于继续往下执行)。若调用进程没有子进程,该函数立即返回;若它的子进程已经结束,该函数同样会立即返回,并且会回收那个早已结束进程的资源。所以,wait0)函数的主要功能为回收已经结束子进程的资源。如果参数 status 的值不是 NULL,wait() 就会把进程退出时的状态取出并存入其中,这是一个整数值(int),指出了子进程是正常退出还是被非正常结束。这个退出信息在一个 int 中包含了多个字段,直使用这个值是没有意义的,我们需要用宏定义取出其中的每个字段。
宏函数可分为如下三组:
宏函数可分为如下三组
WIFEXITED(status) 为非0一进程正常结束 WEXITSTATUS(status) 如上宏为真,使用此宏 一>获取进程退出状态 (exit的参数)
WIFSIGNALED(status) 为非0 一>进程异常终止 WTERMSIG(status) 如上宏为真,使用此宏 一>取得使进程终止的那个信号的编号
WIFSTOPPED(status) 为非0 一>进程处于暂停状态 WSTOPSIG(status) 如上宏为真,使用此宏 一>取得使进程暂停的那个信号的编号 WIFCONTINUED(status) 为真 一>进程暂停后已经继续运行
示例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
//区分父子进程
int main(void)
{
int ret = -1;
int status = 0;
pid_t pid =-1;
//创建一个子进程在父进程中返回子进程的pid
//fork函数在子进程中返回0
pid = fork();
if(pid <0)
{
// 没有创建成功
perror("fork");
return 0;
}
if (0 == pid)
{
//子进程
for(int i = 0; i <5;i++)
{
printf("child proces [%d] do thing %d \n", getpid(),i+1);
sleep(1);
}
// 子进程终止
exit(10);
}
//父进程
printf("父进程等待子进程退出,回收其资源\n");
ret = wait(&status);
if( -1 == ret ) {
perror("wait");
return 1;
}
printf("父进程回收了子进程资源, status=%d\n",status);
//属于正常退出
if (WIFEXITED(status))
{
printf("子进程退出状态码: %d\n",WEXITSTATUS(status));
}
else