#include
#include
#include
#include
#include
int w =1;
//int w1= 1;
//int w2= 1;
void quit(int sig)
{
printf("received
the SIGQUIT signal");
}
void oops(int sig)
{
w
= 0;//change the value of w, so that the process
will skip out of while(w)
printf("child
receivedinterrupt\n");
}
void stop_wait(int sig)
{
w
= 0;//change the value of w, so that the process
will skip out of while(w)
}
int main()
{
pid_t
pid1, pid2;
pid1
= fork();
if(pid1
== 0)
{
printf("child_1\n");
printf("in
child_1 w =%d\n", w);
//the
value of w is copied from parent process, that is
w=1
signal(SIGINT,
SIG_IGN);//ingnore the SIGINT ^C
(void)signal(SIGUSR1,
oops);//it must be executed before
while(w)
while(w);//do
nothing until receive SIGINT from parent
printf("in
child_1 after oops w = %d\n", w);
printf("child_1
is killed by parent\n");
exit(0);//exit
from current process
}
else
if(pid1 > 0)
{
pid2
= fork();
if(pid2
== 0)
{
printf("child_2\n");
printf("in
child_2 w =%d\n", w);
//the
value of w is copied from parent process, that is
w=1
(void)signal(SIGUSR1,oops);//it
must be executed before while(w)
signal(SIGINT,SIG_IGN);//ignore
^C
while(w);//do
nothing until receive SIGINT from parent
printf("in
child_2 after oops w = %d\n", w);
printf("child_2
is killed by parent\n");
exit(0);//exit
from current process
}
else
if (pid2 > 0) ;
{
printf("parent\n");
signal(SIGQUIT,
quit);
signal(SIGINT,
stop_wait);//it must be executed before
while(w)
while(w);//do
nothing until receive ^C
printf("stop wait\n");
kill(pid1,
SIGUSR1);
kill(pid2,
SIGUSR1);
sleep(1);//It
is very important to make the parent process wait
for the child process for a moment.The purpose may be avoiding
collision
printf("parent
is killed\n");
exit(0);
}
}
}
通过搜索网页,我从Wikipedia摘到下面这段对SIGQUIT的说明:
SIGQUIT:
On POSIX-compliant platforms, SIGQUIT is
the signal sent to a process by its controlling
terminal when the user requests that the process perform a core
dump. SIGQUIT can usually be induced with Control-\. On Linux, one
may also use Ctrl-4 or, on the virtual console, the SysRq key.
也
就是说,SIGQUIT也是等待来自键盘的一个信号,但是不再是SIGINT所等待的Ctrl+C,而是Ctrl+4。于是我写了
signal(SIGQUIT, quit)而不是signal(SIGQUIT,
SIG-IGN),我想了解一下什么情况下这个信号会被接收,而不是直接忽略掉这个信号。上面这段代码的执行情况如图:

在输入Ctrl+4时,程序并没有什么变化,直到输入Ctrl+C,程序执行了收到SIGQUIT信号时需要执行的函数。
而如果我将signal(SIGQUIT,quit)改为signal(SIGQUIT,SIG-IGN),又会有如下的效果:

我 执行了两次,如果在父进程进入等待状态时直接输入Ctrl+C那么程序不会理会signal(SIGQUIT,
SIG-IGN),执行结果与没有加signal(SIGQUIT,
SIG-IGN)语句是一样的。如果在父进程进入等待状态时,输入Ctrl+4,程序不会响应直到输入Ctrl+C,且程序不会执行对子进程的操作。
同
时需要注意的是SIG系列的信号有很多,每一种被系统定义的信号都有自己的功能和编号。由于对大部分的信号功能不是很了解,我使用的是SIGUSR1、
SIGUSR2这两个用户自定义的信号。同时,我试用过SIGKILL这个信号,书上的解释是它是一个不能被捕获的信号,在实际试用的过程中,若父进程向
子进程发出此信号,子进程会被立即结束掉,而不会出现子进程接收到该信号然后进行一系列操作的情况。
kill -l的查询结果:
1)
SIGHUP 2)SIGINT 3)SIGQUIT 4)
SIGILL 5)SIGTRAP
6)SIGABRT 7)SIGBUS 8)
SIGFPE 9)SIGKILL 10)
SIGUSR1
11)
SIGSEGV 12)SIGUSR2
13)
SIGPIPE
14)SIGALRM 15)SIGTERM
16)SIGSTKFLT 17)SIGCHLD 18)
SIGCONT 19)SIGSTOP 20)SIGTSTP
21)SIGTTIN 22)SIGTTOU 23)SIGURG 24)SIGXCPU 25)SIGXFSZ
26)SIGVTALRM 27)SIGPROF 28)SIGWINCH 29)SIGIO
30)SIGPWR
31)SIGSYS 34)SIGRTMIN 35)SIGRTMIN+1 36)SIGRTMIN+2 37)SIGRTMIN+3
38)SIGRTMIN+4 39)SIGRTMIN+5 40)SIGRTMIN+6 41)SIGRTMIN+7 42)SIGRTMIN+8
43)SIGRTMIN+9 44)SIGRTMIN+10 45)SIGRTMIN+11 46)SIGRTMIN+12
47)SIGRTMIN+13 48)SIGRTMIN+14 49)SIGRTMIN+15 50)SIGRTMAX-14
51)SIGRTMAX-13 52)SIGRTMAX-12 53)SIGRTMAX-11 54)SIGRTMAX-10 55)SIGRTMAX-9
56)SIGRTMAX-8 57)SIGRTMAX-7
58)SIGRTMAX-6 59)SIGRTMAX-5 60)SIGRTMAX-4
61)SIGRTMAX-3 62)SIGRTMAX-2
63)SIGRTMAX-1 64)SIGRTMAX