题目:
编写一段程序,使用系统调用fork( )创建两个子进程,再用系统调用signal( )让父进程捕捉键盘上来的中断信号(即按ctrl+c键),当捕捉到中断信号后,父进程用系统调用kill( )向两个子进程发出信号,子进程捕捉到信号后,分别输出下列信息后终止:
Child process 1 is killed by parent!Parent process is killed!
原始程序:
#include
#include
#include
void go();
void stop1(),stop2();
int p1,p2;
main( )
{
while((p1=fork( ) )==-1); /*创建子进程p1*/
if (p1>0)
{
while((p2=fork( ) )==-1); /*创建子进程p2*/
if(p2>0)
{
printf("This is parent %d.\n", getpid());
signal(SIGINT,go); /*接收到信号,转go*/
pause();
sleep(2); // wait for the operation of child
wait(0);
wait(0);
printf("Parent process is killed!\n");
exit(0);
}
else if(p2 == 0)
{
printf("This is child_2 %d.\n", getpid());
signal(17,stop2); /*接收到软中断信号17,转stop2*/
pause();
}
}
else if(p1 == 0)
{
printf("This is child_1 %d.\n", getpid());
signal(16,stop1); /*接收到软中断信号16,转stop1*/
pause();
}
}
void go()
{
kill(p1,16); /*向p1发软中断信号16*/
kill(p2,17); /*向p2发软中断信号17*/
}
void stop2()
{
printf("Child process 2 is killed by parent!\n");
exit(0);
}
void stop1()
{
printf("Child process 1 is killed by parent!\n");
exit(0);
}
在输入Ctrl+C后,父进程和子进程同时结束了,子进程并没有处理为其设置的信号,是什么原因呢?
因为子进程从父进程中继承了Ctrl+C信号,及其默认的处理程序,在子进程中并没有屏蔽Ctrl+C信号,因此,当输入Ctrl+C信号时,子进程会在处理父进程为其指定的信号之前,调用默认的处理Ctrl+C信号的程序,直接退出。因此,解决这个问题的办法,就是在子进程中屏蔽掉系统默认的对Ctrl+C信号的处理,如下:
#include
#include
#include
#include
#include
#include
#include
#include
void go();
void stop1(),stop2();
pid_t p1,p2;
void main( )
{
int status = -1;
int rtv;
while((p1=fork( ) )==-1); /*创建子进程p1*/
if (p1>0)
{
while((p2=fork( ) )==-1); /*创建子进程p2*/
if(p2>0)
{
printf("Parent process %d\n", getpid());
signal(SIGINT,go); /*接收到信号,转go*/
pause();
sleep(2);
wait(NULL);
wait(NULL);
printf("Parent process is killed!\n");
exit(0);
}
else
{
printf("Process 2, pid %d\n", getpid());
signal(SIGINT, SIG_IGN); //屏蔽默认的 SIGINT信号处理
signal(SIGUSR2, stop2);
if(signal(SIGUSR2,stop2) == SIG_ERR) {
printf("Can't catch SIGUR2");
}
pause();
printf("Process 2 End\n");
}
}
else
{
printf("Process 1, pid %d\n", getpid());
signal(SIGINT, SIG_IGN); //屏蔽默认的 SIGINT信号处理
if(signal(SIGUSR1,stop1) == SIG_ERR) {
printf("Can't catch SIGUR2");
}
pause();
printf("Process 1 End\n");
}
printf("child exit status is %d\n", WEXITSTATUS(status));
}
void go()
{
int rtv;
printf("Func go\n");
rtv = kill(p1,SIGUSR1); /*向p1发软中断信号16*/
if(rtv) {
printf("fail to send signal 16 to p1\n");
} else {
printf("Succed in sending signal 16 to p1\n");
}
rtv = kill(p2,SIGUSR2); /*向p2发软中断信号17*/
if(rtv) {
printf("fail to send signal 17 to p2\n");
} else {
printf("Succed in sending signal 17 to p2\n");
}
}
void stop2()
{
printf("Child process 2 is killed by parent!\n");
exit(0);
}
void stop1()
{
printf("Child process 1 is killed by parent!\n");
exit(0);
}