SIGCHLD的产生条件
1、子进程终止时
2、子进程接收到SIGSTOP信号停止时
3、子进程处在停止态,接受到SIGCONT后唤醒时
举例:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.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(void)
{
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 = 18;
while (n--)
{
printf("child ID %d\n", getpid());
sleep(1);
}
return i;
}
else if (pid > 0)
{
//先设置捕捉
//再解除对SIGCHLD的阻塞
struct sigaction act;
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;
}
执行结果:
child ID 4170
child ID 4171
child ID 4169
child ID 4172
child ID 4168
child ID 4166
child ID 4165
child ID 4164
child ID 4163
child ID 4170
Parent ID 4162
child ID 4167
child ID 4171
child ID 4169
child ID 4172
child ID 4168
child ID 4166
child ID 4165
child ID 4164
child ID 4163
Parent ID 4162
child 4167 exit 4
child 4170 exit 7
Parent ID 4162
child 4169 exit 6
child 4171 exit 8
Parent ID 4162
child 4168 exit 5
child 4172 exit 9
Parent ID 4162
child 4166 exit 3
Parent ID 4162
child 4165 exit 2
Parent ID 4162
child 4164 exit 1
Parent ID 4162
child 4163 exit 0
Parent ID 4162
Parent ID 4162
Parent ID 4162
^C
waitpid参数讲解:
pid_t waitpid(pid_t pid, int *status, int options)
options
WNOHANG
没有子进程结束,立即返回
WUNTRACED
如果子进程由于被停止产生的SIGCHLD, waitpid则立即返回
WCONTINUED
如果子进程由于被SIGCONT唤醒而产生的SIGCHLD, waitpid则立即返回
获取status
WIFEXITED(status)
子进程正常exit终止,返回真
WEXITSTATUS(status)返回子进程正常退出值
WIFSIGNALED(status)
子进程被信号终止,返回真
WTERMSIG(status)返回终止子进程的信号值
WIFSTOPPED(status)
子进程被停止,返回真
WSTOPSIG(status)返回停止子进程的信号值
WIFCONTINUED(status)
子进程由停止态转为就绪态,返回真