对while((pid = waitpid(-1, &stat, WNOHANG)) > 0)不懂的地方,现在懂了

while((pid = waitpid(-1, &stat, WNOHANG)) > 0)

需要写到信号处理函数中,假如有10个子进程

只要父进程能够收到最后一个信号,就能把前面丢失的所产生的僵尸进程回收完.

而父进程是能够收到最后一个信号的,就算父进程在子进程结束到第5个的时候,开始进行信号函数的处理.

如果由于处理时间过长,导致剩下5个也在处理函数执行的过程中结束掉.这时,由于信号处理机制会导致剩下5个传递的信号会被阻塞,当然由于该信号不排队

所以未决集只会有一个信号(当阻塞集相应位至1时,如果有相应信号到达,未决集至1,表示有未决的信号).至此,子进程已经全部结束,当信号函数执行完毕后,内核开放阻塞信号集,那么.之前被阻塞掉的那个信号传递进来.

接下来再次回收剩下的僵尸进程.

下面将给出代码,显示,信号函数的执行次数与回收次数的计数.就能看出区别

void hander(int n)
{
    static int i = 0;
    i++;
    printf("    i:%d\n", i);
    while (waitpid(0, NULL, WNOHANG) > 0)
   	{
   		    static int j = 0;
    		j++;
    		printf("j:%d\n", j);
   	}

}

  

waitpid(-1, &stat, WNOHANG)回收子进程,回收成功一个,返回子进程的pid,

如果WNOHANG被指定,将不再阻塞回收,此时的返回规则是.如果有子进程,但没有结束(没有变成僵尸进程),waitpid返回0,如果有僵尸进程,回收一个僵尸进程,返回僵尸进程pid,所以要用循环去处理.把僵尸进程回收完

时间: 2024-09-29 21:04:11

对while((pid = waitpid(-1, &stat, WNOHANG)) > 0)不懂的地方,现在懂了的相关文章

linux wait 和waitpid

背景:在读unix网络编程卷1, 第五章服务器处理SIGCHLD信号时.及多个客户端同时关闭socket连接,服务端主进程的多个子进程几乎同时结束. 使用wait 的情况: void sig_chld(int signo) { pid_t pid; int stat; pid = wait(&stat); return; } 当服务端采用并发处理客户端的请求时,客户进程关闭连接,服务端子进程几乎同时结束,信号处理函数在使用wait时,并不能完全的防止僵尸进程的出现,问题在于,信号处理函数在处理第

waitpid和SIGCHLD信号回收僵尸进程

对于多进程而言,父进程一般需要跟踪子进程的退出状态.因此当子进程结束运行时,内核不会立即释放该进程的进程表的表项.以满足父进程后续对子进程退出的信息查询(死后验尸),当然前提是父进程还在运行.在子进程结束之后,父进程读取其退出状态之前,我们称该子进程处于僵尸态(用户空间已经被释放,其不能被调度). 先介绍两个系统调用函数: #include <sys/types.h> #include <sys/wait.h> pid_t wait(int *status);// wait是一个阻

wait和waitpid

wait和waitpid 2012-10-26 16:41:39 分类: LINUX 当有多个子进程的SIGCHLD信号到达父进程的时候,如果父进程用wait等待,那么父进程在处理第一个达到的SIGCHLD信号的时候,其他的SIGCHLD信号被堵塞,而且信号不被缓存,这样就会导致信号丢失,这样会产生很多的僵尸进程..解决办法是父进程用waitpid来等待子进程信号... 正好看到有人问这样一个问题 看unix网络编程第一卷的时候,碰到书上这样一个例子: 一个并发服务器, 每一个客户端连接服务器就

Linux网络编程wait()和waitpid()的讲解

本文讲的是关于wait和waitpid两者的区别与联系.为避免僵尸进程的产生,无论我们什么时候创建子进程时,主进程都需要等待子进程返回,以便对子进程进行清理.为此,我们在服务器程序中添加SIGCHLD信号处理函数. 客户端断开连接后,服务器端存在大量僵尸进程.这是由于服务器子进程终止后,发送SIGCHLD信号给父进程,而父进程默认忽略了该信号.为避免僵尸进程的产生,无论我们什么时候创建子进程时,主进程都需要等待子进程返回,以便对子进程进行清理.为此,我们在服务器程序中添加SIGCHLD信号处理函

TCP客户/服务器编程入门

最近在学习UNP,特此记录. 1. TCP回射服务器程序 #include "unp.h" void str_echo(int sockfd) { ssize_t n; char buf[MAXLINE]; again: while ( (n = read(sockfd, buf, MAXLINE)) > 0) Writen(sockfd, buf, n); if (n < 0 && errno == EINTR) goto again; else if (

Linux下异步回收子进程

背景 我们知道,当一个进程fork出子进程后,没有对子进程进行回收,那么子进程运行完之后的状态会变为僵尸进程. 我们可以通过wait和waitpid来回收子进程,防止僵尸进程的出现. 但是wait和waitpid,要么以阻塞方式运行,要么以轮询方式运行,都极大的占用了CPU资源. 本文将介绍,父进程如何通过异步操作回收子进程! 原理 在每个子进程运行完成之后,都会向父进程发出SIGCHLD信号.而在默认情况下,父进程会忽略掉该信号.因此,我们只需要对SIGCHLD信号进行捕捉,即可异步对子进程进

不可靠信号SIGCHLD丢失的问题

如果采用 void sig_chld(int signo) {        pid_t pid;        int stat;                while((pid = waitpid(-1, &stat, WNOHANG)) > 0){                printf("child %d terminated\n", pid);        }         return; } 来处理子进程退出的问题,那么如果多个SIGCHLD叠加,

孤儿进程和僵尸进程

孤儿进程和僵尸进程 一.定义:什么是孤儿进程和僵尸进程 僵尸进程:一个子进程在其父进程还没有调用wait()或waitpid()的情况下退出.这个子进程就是僵尸进程. 孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程.孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作. 僵尸进程将会导致资源浪费,而孤儿则不会. 子进程持续10秒钟的僵尸状态(EXIT_ZOMBIE)------------------------------

unix网络编程代码(2)

继续贴<unix网络编程>上的示例代码.这次是一个反射程序,反射是客户端讲用户输入的文本发送到服务器端,服务器端读取客户端发过来的文本消息,然后原封不动的把文本消息返回给客户端.使用tcp协议连接客户端和服务端,我已经在我的阿里云服务器上测试过了,能够完美运行. 首先是头文件wrap.h,在该头文件中,声明了封装部分网络编程套接字api的包裹函数,以及某些宏定义. 1 #ifndef WRAP_H_ 2 #define WRAP_H_ 3 4 #include <stdio.h>