资讯详情

关于SIGCHLD信号

用wait和waitpid函数清理僵尸过程,父亲的过程可以阻止等待子过程结束,也可以查询是否有子过程结束等待清理(即轮询)。在第一种方式下,如果父亲的过程被阻塞,他就无法处理自己的工作;在第二种方式下,父亲的过程应该记住在处理自己的工作时不时地轮流询问。程序很复杂。

事实上,当子过程终止时,发送给父亲SIGCHLD该信号的默认处理动作被忽略,父亲的过程可以自定义SIGCHLD信号处理函数,所以父亲的过程只需要专注于自己的工作,不需要关心子过程,子过程终止将通知父亲的过程,父亲的过程在信号处理函数中调用wait清理子过程即可。

编写个程序:父过程:fork出子过程,子过程调用exit(2)终止,自定义父亲的过程SIGCHLD其中调用信号处理函数wait获取子过程的退出状态并打印。

#include "./common/head.h"  /*功能:  *子过程正常死亡(exit),发出SIGCHLD信号;父亲的过程绑定了信号的处理函数,并收集了它。 */  ///父进程给子进程收尸的处理函数 void sig_child(int signo){     int sts;     pid_t pid = wait(&sts);     if(WIFEXITED(sts)){    ///子过程正常死亡         printf("proc:%d exit with code %d\n", pid, WEXITSTATUS(sts));     }     return ; }  int main() {     pid_t pid = fork();     if(pid < 0){         perror("fork");         exit(1);     }      if(pid){    //父进程         printf("child pid = %d\n", pid);          ///         struct sigaction newact, oldact;                  newact.sa_handler = sigchild;         sigemptyset(newact.sa_mask);         newact.sa_flags = 0;          sigaction(SIGCHLD, &newact, &oldact);          ///父亲一直在工作         int n = 10;         while(n--){             printf("work~\n");             sleep(1);         }      }else{    //子进程         sleep(2);         exit(2);     }       return 0; }  

事实上,因为UNIX由于历史原因,还有另一种方法可以避免僵尸过程:父亲过程调用sigaction将SIGCHLD处理动作为SIG_IGN,这样fork子过程在终止时会自动清,不会产生僵尸流程,也不会通知父流程。此方法对于Linux可用,但不保证在其他地方UNIX可用于系统。编程验证不会产生僵尸过程。

#include "./common/head.h"  /*功能:  *父进程将SIGCHLD设置信号的处理函数SIG_IGN,子过程正常死亡(exit),这时子进程会自动清理自己的尸体,不会发送SIGCHLD。 */  ///父进程给子进程收尸的处理函数 void sig_child(int signo){     int sts;     pid_t pid = wait(&sts);     if(WIFEXITED(sts)){    ///子过程正常死亡         printf("proc:%d exit with code %d\n", pid, WEXITSTATUS(sts));     }     return ; }  int main() {     pid_t pid = fork();     if(pid < 0){         perror("fork");         exit(1);     }      if(pid){    //父进程         printf("child pid = %d\n", pid);          ///         struct sigaction newact, oldact;                  newact.sa_handler = SIG_IGN;    ///父进程对SIGCHLD设置信号处理动作SIG_IGN以后,子过程会自动处理自己的尸体,不会产生僵尸过程,也不会通知父亲过程。         sigemptyset(newact.sa_mask);         newact.sa_flags = 0;          sigaction(SIGCHLD, &newact, &oldact);          ///父亲一直在工作         int n = 10;         while(n--){             printf("work~\n");             sleep(1);         }      }else{    //子进程         sleep(2);         exit(2);     }       return 0; }  

标签: 2sa1611三极管2sa1106三极管

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台