您的位置:首页 > 运维架构 > Linux

Linux编程signal函数使用

2013-04-12 16:29 369 查看
题目:

编写一段程序,使用系统调用fork( )创建两个子进程,再用系统调用signal( )让父进程捕捉键盘上来的中断信号(即按ctrl+c键),当捕捉到中断信号后,父进程用系统调用kill( )向两个子进程发出信号,子进程捕捉到信号后,分别输出下列信息后终止:  

        Child process 1 is killed by parent!
        Child process 2 is killed by parent!
父进程等待两个子进程终止后,输出以下信息后终止:
        Parent process is killed!

原始程序:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

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);
}
但是这段程序,并没有按照预期的结果,输出“Child process 1 is killed by parent”和"Child process 2 is killed by parent!"。
在输入Ctrl+C后,父进程和子进程同时结束了,子进程并没有处理为其设置的信号,是什么原因呢?

因为子进程从父进程中继承了Ctrl+C信号,及其默认的处理程序,在子进程中并没有屏蔽Ctrl+C信号,因此,当输入Ctrl+C信号时,子进程会在处理父进程为其指定的信号之前,调用默认的处理Ctrl+C信号的程序,直接退出。因此,解决这个问题的办法,就是在子进程中屏蔽掉系统默认的对Ctrl+C信号的处理,如下:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>

#include <unistd.h>
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);
}


参考:UNIX环境高级编程_第二版中文
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: