Linux下父进程异步等待子进程
2017-07-17 10:00
239 查看
1. 背景知识
我们可以使用wait和waitpid函数清理僵死进程,父进程可以阻塞等待子进程结束,也可以非阻塞地查询是否有子进程结束等待清理(也就是轮询的方式)。采用第一种方式,父进程阻塞了就不能处理自己的工作了;采用第二种方式,程序实现复杂。其实,子进程在终止时会给父进程发SIGCHLD信号,该信号的默认处理动作是忽略,父进程可以自定义SIGCHLD信号的处理函数,这样父进程只需专心处理自己的工作,不必关心子进程了,子进程终止时会通知父进程,父进程在信号处理函数中调用wait清理子进程即可。
如果我们以排队等待的方式等待的话:当第一个进程发送SIGCHILD时,父进程处理;第二个进程发送SIGCHILD阻塞等待,待处理;当有一个待处理的信号时,如果有第三个SIGCHILD信号发送,将不会不处理,直接被丢弃,无法回收这个僵死进程。
2. 相关函数介绍
参数:
pid:进程ID。
pid > 0时, 只等待进程ID等于pid的子进程。
pid = -1时,等待任何一个子进程,和wait的作用一样。
pid = 0时, 等待同一个进程组中的任何子进程。
pid < -1时,等待进程组id与pid绝对值相等的任意子进程。
status:输出型参数,拿回子进程的退出信息。
option: 可选操作,为0时作用同wait。
WNOHANG:非阻塞方式(轮询式访问)等待子进程。
WCONTINUED:若实现支持作业控制,那么由pid指定的任一子进程在暂停后已经继续,但状态尚未报告,则返回状态。
WUNTRACED:如果子进程进入暂停执行则马上返回,但结束状态不予以例会。
返回值:正常返回子进程的进程ID,出错,返回-1;如果设置了WNOHANG,当waitpid发现没有已退出的子进程,返回0。
3. 测试异步等待
代码
测试结果
我们可以使用wait和waitpid函数清理僵死进程,父进程可以阻塞等待子进程结束,也可以非阻塞地查询是否有子进程结束等待清理(也就是轮询的方式)。采用第一种方式,父进程阻塞了就不能处理自己的工作了;采用第二种方式,程序实现复杂。其实,子进程在终止时会给父进程发SIGCHLD信号,该信号的默认处理动作是忽略,父进程可以自定义SIGCHLD信号的处理函数,这样父进程只需专心处理自己的工作,不必关心子进程了,子进程终止时会通知父进程,父进程在信号处理函数中调用wait清理子进程即可。
如果我们以排队等待的方式等待的话:当第一个进程发送SIGCHILD时,父进程处理;第二个进程发送SIGCHILD阻塞等待,待处理;当有一个待处理的信号时,如果有第三个SIGCHILD信号发送,将不会不处理,直接被丢弃,无法回收这个僵死进程。
2. 相关函数介绍
#include<sys/types.h> #include<sys/wait.h> pid_t waitpid(pid_t pid,int* status,int options);
参数:
pid:进程ID。
pid > 0时, 只等待进程ID等于pid的子进程。
pid = -1时,等待任何一个子进程,和wait的作用一样。
pid = 0时, 等待同一个进程组中的任何子进程。
pid < -1时,等待进程组id与pid绝对值相等的任意子进程。
status:输出型参数,拿回子进程的退出信息。
option: 可选操作,为0时作用同wait。
WNOHANG:非阻塞方式(轮询式访问)等待子进程。
WCONTINUED:若实现支持作业控制,那么由pid指定的任一子进程在暂停后已经继续,但状态尚未报告,则返回状态。
WUNTRACED:如果子进程进入暂停执行则马上返回,但结束状态不予以例会。
返回值:正常返回子进程的进程ID,出错,返回-1;如果设置了WNOHANG,当waitpid发现没有已退出的子进程,返回0。
3. 测试异步等待
代码
#include<stdio.h> #include<signal.h> #include<unistd.h> #include<errno.h> #include<sys/types.h> #include<stdlib.h> void handler(int sig) { pid_t id; while((id = waitpid(-1, NULL, WNOHANG)) > 0) { printf("wait child sucess: %d\n",id); } } int main() { signal(SIGCHLD,handler); pid_t id=fork(); if(id==0) { printf("child1 id: %d\n",getpid()); sleep(3); exit(1); } pid_t id2=fork(); if(id2==0) { printf("child2 id: %d\n",getpid()); sleep(5); exit(2); } pid_t id3=fork(); if(id3==0) { printf("child3 id: %d\n",getpid()); sleep(7); exit(3); } printf("father id: %d\n",getpid()); while(1) { printf("father do self \n"); sleep(1); } return 0; }
测试结果
相关文章推荐
- Linux父进程对于子进程的异步等待
- 进程等待及子进程异步等待方式
- 验证子进程退出时会给父进程发送信号的机制 、 编写父进程等待子进程的异步版本
- 【Linux】子进程的异步等待方式
- Linux信号(一)——子进程的异步等待方式
- Linux退出进程exit/_exit和等待子进程退出wait函数分析
- 【Linux】子进程的异步等待方式
- linux下的wait()实现等待一个子进程和所有子进程退出
- Linux下子进程的异步等待
- 【Linux】子进程的异步等待方式
- LinuxC/C++编程(3)—异步清理子进程(避免成为僵尸进程)
- 父进程异步等待子进程
- Linux下利用fork()创建子进程并使父进程等待子进程结束
- Linux查看进程的所有子进程和线程
- linux下的C语言开发(进程等待)
- linux程序设计——父进程和子进程(第十三章)
- linux中父进程退出时如何通知子进程
- Linux 进程控制——等待队列详解(二)
- Linux使用wake_up_interruptible()唤醒注册到等待队列上的进程
- Linux中,子进程与父进程的继承关系