signal与kill题目要求
编写程序,使用系统调用 fork()创建两个子进程,再用系统调用 signal()让父进程
捕捉键盘上发出的中断信号(即按 ctrl+c 或是 ctrl+\键),5 秒钟内若父进程未接收到 这两个软中断的某一个,则父进程用系统调用 kill()向两个子进程分别发送软中断信号
SIGUSR1 和 SIGUSR2,子进程获得对应的软中断信号,然后分别输出下列信息后终止:
Child process (pid=?) be killed!
Child process (pid=?) be killed!
父进程调用 wait()函数等待两个子进程终止后,输出以下信息,结束进程执行:
Parent process (pid=?) finished!
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void ParentStop(){
return;
}
void ChildStop(){
printf("Child process (pid=%d) be killed\n", getpid());
exit();
}
int main(){
pid_t p1, p2;
p1=fork();
if (p1){
//parent
p2=fork();
if (p2){
//parent
signal(SIGINT, ParentStop);
signal(SIGQUIT, ParentStop);
sleep(5);
kill(p1, SIGUSR1);
kill(p2, SIGUSR2);
wait(NULL);
wait(NULL);
printf("Parent process (pid=%d) finish\n", getpid());
}else{
//child2
signal(SIGUSR2, ChildStop);
sleep(6);
}
}else{
//child1
signal(SIGUSR1, ChildStop);
sleep(6);
}
return 0;
}
父进程中用signal函数把SIGQUIT和SIGINT信号所指向的函数改成了自己编写的ParentStop函数,中间什么也不做直接返回。所以收到ctrl+\和ctfl+c的时候不会被结束而是调用了函数之后继续执行下面的语句。
利用kill函数在父进程中向两个子进程发送sigusr1信号和sigusr2信号,而两个子进程接收这两个信号的动作都是输出一条语句之后exit。
所以这个程序的运行结果就是:
当执行中不给程序ctrl+\和ctfl+c信号的时候,父进程会给子进程发送信号。
当执行过程中给了ctrl+\和ctfl+c信号之后。由于两个子进程是从父进程中继承来的,父进程是从shell进程继承来的,他们都有对stdin和stdout的读写权限。所以都会接收到结束信号。这时父进程由于改变了执行动作,所以父进程执行结果不变,而两个子进程不会再输出语句了。
注意signal的声明具有一次性,即它声明后,当进程收到指定信号会跳转到指定函数去执行, 并且会把这个信号的指定效果恢复成默认值。当这个进程再次接受到这个信号后,就不会在去执行我们指定的函数了。
如果有需要的话需要在接受信号之前再次调用signal函数来声明。