一、SIGCHLD信号
1. SIGCHLD简介
SIGCHLD的产生条件:
- 子进程终止
- 子进程接收到SIGSTOP信号停止时
- 子进程处于停止状态,接收到SIGCONT后唤醒
注意:通过signal(SIGCHLD, SIG_IGN)通知内核对子进程的结束不关心,由内核回收。如果不想让父进程挂起,可以在父进程中加入一条语句:signal(SIGCHLD,SIG_IGN);表示父进程忽略SIGCHLD信号,该信号是子进程退出的时候向父进程发送的。
2. 测试代码:
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>void sys_err(char* str)
{perror(str);exit(1);
}void do_sig_child(int signo)
{int status;pid_t pid;while ((pid = waitpid(0, &status, WNOHANG)) > 0){if (WIFEXITED(status))printf("---------------------------child %d exit %d\n", pid, WEXITSTATUS(status));else if (WIFSIGNALED(status))printf("child %d cancel signal %d\n", pid, WTERMSIG(status));}
}int main()
{pid_t pid;int i;for (i = 0; i < 10; i++){if ((pid = fork()) == 0)break;else if (pid < 0)sys_err("fork");}if (pid == 0) //子进程{int n = 1;while (n--){printf("child ID %d\n", getpid());sleep(1);}return i + 1;}else if (pid > 0) //父进程{struct sigaction act; act.sa_handler = do_sig_child;sigemptyset(&act.sa_mask);act.sa_flags = 0;sigaction(SIGCHLD, &act, NULL); while (1){printf("parent ID %d\n", getpid());sleep(1);}}return 0;
}
输出结果:
2. 测试代码:
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>void sys_err(char* str)
{perror(str);exit(1);
}void do_sig_child(int signo)
{int status;pid_t pid;if((pid = waitpid(0, &status, WNOHANG)) > 0){if (WIFEXITED(status))printf("---------------------------child %d exit %d\n", pid, WEXITSTATUS(status));else if (WIFSIGNALED(status))printf("child %d cancel signal %d\n", pid, WTERMSIG(status));}
}int main()
{pid_t pid;int i;for (i = 0; i < 10; i++){if ((pid = fork()) == 0)break;else if (pid < 0)sys_err("fork");}if (pid == 0) //子进程{int n = 1;while (n--){printf("child ID %d\n", getpid());sleep(1);}return i + 1;}else if (pid > 0) //父进程{struct sigaction act; //SIGCHLD阻塞act.sa_handler = do_sig_child;sigemptyset(&act.sa_mask);act.sa_flags = 0;sigaction(SIGCHLD, &act, NULL); //解除对SIGCHLD的阻塞 while (1){printf("parent ID %d\n", getpid());sleep(1);}}return 0;
}
输出结果:
三、参考资料:
- linux下的僵尸进程处理SIGCHLD信号
- 孤儿进程与僵尸进程[总结]