子进程的异步等待

来源:互联网 发布:经期 知乎 编辑:程序博客网 时间:2024/05/18 03:06
一 对于wait和waitpiwd的介绍
wait:
pid_t wait(int *status)    

   进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。 

参数:
   参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为NULL,就象下面这样:
pid = wait(NULL);

waitpid:
pid_t waitpid(pid_t pid,int *status,int options)

   从本质上讲,系统调用waitpid和wait的作用是完全相同的,但waitpid多出了两个可由用户控制的参数pid和options,从而为我们编程提供了另一种更灵活的方式。

参数:(status同上)     

pid:从参数的名字pid和类型pid_t中就可以看出,这里需要的是一个进程ID。但当pid取不同的值时,在这里有不同的意义。     
pid>0时,只等待进程ID等于pid的子进程,不管其它已经有多少子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去。

pid=-1时,等待任何一个子进程退出,没有任何限制,此时waitpid和wait的作用一模一样。   

pid=0时,等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,waitpid不会对它做任何理睬。

pid<-1时,等待一个指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值。   

options: options提供了一些额外的选项来控制waitpid,目前在Linux中只支持WNOHANGWUNTRACED两个选项,这是两个常数,可以用"|"运算符把它们连接起来使用

wait和waitpid的区别

waitpid提供了wait函数不能实现的3个功能: 
1.waitpid等待特定的子进程, 而wait则返回任一终止状态的子进程; 
2.waitpid提供了一个wait的非阻塞版本; 
3.waitpid支持作业控制(以WUNTRACED选项). 用于检查wait和waitpid两个函数返回终止状态的宏: 这两个函数返回的子进程状态都保存在status指针中,用以下3个宏可以检查该状态: 
   WIFEXITED(status): 若为正常终止, 则为真. 此时可执行 WEXITSTATUS(status): 取子进程传送给exit或_exit参数的低8位. 
   WIFSIGNALED(status): 若为异常终止, 则为真.此时可执行 WTERMSIG(status): 取使子进程终止的信号编号.

   WIFSTOPPED(status):若为当前暂停子进程, 则为真. 此时可执行 WSTOPSIG(status): 取使子进程暂停的信号编号

二证明子进程退出时会返回SIGCHLD信号

  1 #include<stdio.h>                                                                                                                                          2 #include<stdlib.h>  3 #include<signal.h>  4 #include<unistd.h>  5 #include<sys/types.h>  6   7 void handler()  8 {  9     printf("father is catching,child is quit"); 10 } 11  12 int main() 13 { 14     signal(SIGCHLD,handler); 15     pid_t pid = fork(); 16     if(pid == 0)//child 17     { 18         printf("child:my pid is %d\n",getpid()); 19         sleep(2); 20         exit(-1); 21  22     } 23  24     while(1) 25     { 26         printf("father is dong somrthing..\n"); 27         sleep(1); 28     } 29     return 0; 30 }~      
代码运行的结果为
在子进程退出时确实会给父进程发出SIGCHLD信号

三 子进程的异步等待方式
代码:
 1 #include<stdio.h>                                                                                                                                                                                                                          2 #include<stdlib.h>  3 #include<signal.h>  4 #include<unistd.h>  5 #include<sys/types.h>  6 #include<sys/wait.h>  7   8   9 void handler(int sig) 10 { 11     printf("father is catching,child is quit\n"); 12  13     pid_t id; 14     while((id = waitpid(-1,NULL,WNOHANG)) > 0) 15     { 16         printf("wait child success:%d\n",id); 17     } 18 } 19  20 int main() 21 { 22     signal(SIGCHLD,handler); 23     pid_t pid1 = fork(); 24         if(pid1 == 0)//child1 25         { 26             printf("child1: my pid is %d\n",getpid()); 27             exit(-1);//child1 is a unusual quit 28         } 29  30     pid_t pid2 = fork(); 31     if(pid2 == 0 )//child2 32     { 33         printf("child3: my pid is %d\n",getpid()); 34         exit(-1);//child2 is a unusual quit; 35     } 36  37     pid_t pid3 = fork(); 38     if(pid3 == 0)//child3 39     { 40         printf("child3: my pid is %d\n",getpid());//child3 is usual  41     } 42  43     while(1)//father 44     { 45         printf("father is doing something\n"); 46         sleep(1); 47     } 48     return 0; 49 }
运行结果如下




原创粉丝点击