编写一个程序,实现:父进程创建两个子进程,然后父进程通过signal()来捕捉键盘发出的CTRL+C键,当按下CTRL+C键后,父进程分别向两个子进程发出SIGUSR1和 SIGUSR2,两个子进程收到信号后分别打印 “ child1 is killed by parent ! ” “ child2 is killed by parent ! ”, 父进程等待两个子进程都退出后,输出“parent is finished”退出
//
//注意:一次wait或waitpid调用只能清理一个子进程,清理多个子进程应使用循环。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
pid_t pid1,pid2;
//信号处理回调函数
void signal_handler(int signo)//signo为触发的信号,为signal()的第一个参数
{
if(signo == SIGINT){
printf("pid1=%d\n",pid1);
kill(pid1,SIGUSR1);
kill(pid2,SIGUSR2);
}
else if(signo == SIGUSR1 ){
printf("child1 is kill by parent1\n");
exit(0);
}
else if(signo == SIGUSR2){
printf("child2 is kill by parent1\n");
exit(0);
}
}
int main(int argc, char const *argv[])
{
pid1 = fork();
pid2 = fork();
int n = 2,wpid;
if(pid1 == 0){
// printf("%d\n",getpid() );
signal(SIGUSR1,signal_handler);
//不能够让子进程因为触发Ctrl+c的信号终止否则没有进行接收到信号指令
signal(SIGINT,SIG_IGN);
pause();//捕捉信号
//考虑执行程序以后直接从pause 退出呢?还是先执行函数在推行湖呢
exit(1);
}
else if(pid1<0){
perror("fork");
exit(-1);
}
if(pid2 == 0){
signal(SIGUSR2,signal_handler);
signal(SIGINT,SIG_IGN);
pause();//捕捉信号
//考虑执行程序以后直接从pause 退出呢?还是先执行函数在推行湖呢
exit(1);
}
else if(pid2<0){
perror("fork");
exit(-1);
}
//首先要捕捉信号Ctrl+z
struct sigaction act , oact;
//指定信号处理回调函数
act.sa_handler = signal_handler;
//阻塞为空
sigemptyset(&act.sa_mask);
//指定调用 signal_handler
act.sa_flags = SA_SIGINFO;//0?
//注册信号
sigaction(SIGINT, &act, &oact);
pause();//捕捉信号
//等待退出回收资源
sleep(1);
printf("i am parent. pid = %d\n",getpid());
while(n>0)
{
wpid=waitpid(-1,NULL,WNOHANG);
/*waitpid函数当第三个参数为WNOHONG时,如果子进程未结束则返回0,
子进程结束调用成功返回子进程的pid.*/
if(wpid>0)//waipid调用成功
n--;
}
printf("wait finish.\n");
return 0;
}