大家都知道一个子进程结束后会变成僵尸态进程,编程时往往会调用wait函数,但是wait()函数通常会引发阻塞,故我们常采用wait_pid()函数:
wait_pid()函数原型为 pid_t wait_pid(pid_t pid,int *status,int options);
参数status:返回进程改变的状态
参数options: WUNTRANCED ------R->T
WCONTINUED -------T->R
参数pid:
pid >0: 探测此时指定的PID子进程
pid = -1: 此时探测任意一个子进程
pid = 0:探测 与父进程同组的子进程的改变
例如: 1.写出与wait()等价的wait_pid函数
wait_pid(-1,&status,0);
2.探测任意子进程,状态从R->Z 、T->R
wait_pid(-1,NULL,WUNTRACED | WCONTINUED);
3.探测任意子进程,状态从R->Z 、T->R、R->T
wait_pid(-1,NULL,WUNTRACED | WCONTINUED | WNOHANG);
编程案例:写一个程序创建两个子进程,用kill命令改变子进程的状态,用父进程检测子进程的状态的变化
运行效果:
运行两个终端一个运行当前程序(a.out),另一个则输入命令改变子进程的状态
输入: kill -SIGSTOP 5072后的输出:
注意:之所以没有显示子进程2的变化,那是因为程序中执行了
setpgrp();
子进程2已经脱离了当前进程组,而
waitpid(0,&status,WUNTRACED | WCONTINUED | WNOHANG);
只能监测到与父进程同组的子进程状态变化
输入: kill -SIGCONT 5072后的输出:
源代码:
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
pid_t pit,pid;
pid_t pit1;
int status = 0;
if((pit = fork()) == -1)
{
perror("Fail to fork");
exit(EXIT_FAILURE);
}
if(pit > 0)
{
if((pit1 =fork()) == -1)
{
perror("Fail to fork");
exit(EXIT_FAILURE);
}
if(pit1 > 0)
{
printf("the parents process : pid is %d\n",pit1);
while(1)
{
pit1 = waitpid(0,&status,WUNTRACED | WCONTINUED | WNOHANG);
printf("the process status change is %d\n",pit1);
sleep(3);
if(pit1 == 0)
continue;
if(WIFSIGNALED(status))
printf("the child over by signal %d\n ",WTERMSIG(status));
else if(WIFSTOPPED(status))
printf("the child stopped by the signal %d\n",WSTOPSIG(status));
else if (WIFEXITED(status))
printf("the child exit by the signal%d\n",WEXITSTATUS(status));
else if(WIFCONTINUED(status))
printf("the child continue by signal SIGCONT\n");
}
}
if(pit1 == 0)
{
printf("the child process2 pid is %d,the ppid is %d,the pgid is %d\n",
getpid(),getppid(),getpgrp());
sleep(3);
while(1);
}
}
if(pit == 0)
{
printf("the child process1 pid is %d,the ppid is %d,the pgid is %d\n",
getpid(),getppid(),getpgrp());
sleep(3);
setpgrp();
printf("the child process1 pid is %d,the ppid is %d,the pgid is %d\n",
getpid(),getppid(),getpgrp());
while(1);
}
exit(EXIT_SUCCESS);
}