子进程会继承父进程的信号处理函数。
当一个进程fork一个子进程时,子进程会继承父进程的存储映射,所以捕捉函数的地址在子进程中是有意义的,所以子进程会继承父进程的信号处理函数。
特殊的是exec,因为exec运行新的程序后会覆盖从父进程继承来的存储映像,那么信号捕捉函数在新程序中已无意义,所以exec会将原先设置为要捕捉的信号都更改为默认动作。
-
#include <unistd.h>
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <signal.h>
-
static void sig_exit()
-
{
-
printf("sig exit pid=%d,ppid=%d\n",getpid(),getppid());
-
}
-
-
static void sig_alrm()
-
{
-
printf("sig alrm pid=%d,ppid=%d\n",getpid(),getppid());
-
}
-
static void sig_int()
-
{
-
printf("sig int pid=%d,ppid=%d\n",getpid(),getppid());
-
}
-
-
int main()
-
{
-
pid_t pid;
-
int status;
-
int sleep_time=0;
-
struct sigaction act,old_act;
-
-
sigemptyset(&act.sa_mask);
-
act.sa_flags=0;
-
act.sa_handler=sig_exit;
-
sigaction(SIGUSR1,&act,&old_act);
-
-
-
act.sa_handler=sig_alrm;
-
act.sa_flags=0;
-
sigemptyset(&act.sa_mask);
-
sigaction(SIGALRM,&act,&old_act);
-
-
sigemptyset(&act.sa_mask);
-
act.sa_flags=0;
-
act.sa_handler=sig_int;
-
sigaction(SIGINT,&act,&old_act);
-
-
if((pid=fork()) <0)
-
printf("fork() error\n");
-
else if(pid == 0) {
-
printf("pid in chlid =%d\n",getpid());
-
kill(getpid(),SIGUSR1);
-
alarm(2);
-
printf("----------\n");
-
sleep_time=sleep(20);
-
printf("+++++sleep_time=%d+++++++\n",sleep_time);
-
exit(0);
-
}
-
wait(&status);
-
-
printf("parent id =%d,status=[%d]\n",getpid(),status);
-
-
return 0;
-
}
编译运行:
gwwu@hz-dev2.wgw.com:~/test/process>gcc -g signal.c -o a
gwwu@hz-dev2.wgw.com:~/test/process>./a
pid in chlid =6617
sig exit pid=6617,ppid=6616
----------
sig alrm pid=6617,ppid=6616
+++++sleep_time=18+++++++ ////sleep的返回被alarm(2)中断.并且可以知道alarm和sleep交互存在的时候,如果alarm的时间小于sleep的时间,alarm仍然有效。
parent id =6616,status=[0]
gwwu@hz-dev2.aerohive.com:~/test/process>
可见父进程中的信号处理函数在子进程中是有效的,当然子进程也可以定义自己的信号处理函数。
-
#include <unistd.h>
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <signal.h>
-
static void sig_exit()
-
{
-
printf("sig exit pid=%d,ppid=%d\n",getpid(),getppid());
-
}
-
-
static void sig_alrm()
-
{
-
printf("sig alrm pid=%d,ppid=%d\n",getpid(),getppid());
-
}
-
static void sig_int()
-
{
-
printf("sig int pid=%d,ppid=%d\n",getpid(),getppid());
-
}
-
static void sig_child_exit()
-
{
-
printf("sig child exit pid=%d,ppid=%d\n",getpid(),getppid());
-
}
-
-
int main()
-
{
-
pid_t pid;
-
int status;
-
int sleep_time=0;
-
struct sigaction act,old_act;
-
-
sigemptyset(&act.sa_mask);
-
act.sa_flags=0;
-
act.sa_handler=sig_exit;
-
sigaction(SIGUSR1,&act,&old_act);
-
-
-
act.sa_handler=sig_alrm;
-
act.sa_flags=0;
-
sigemptyset(&act.sa_mask);
-
sigaction(SIGALRM,&act,&old_act);
-
-
sigemptyset(&act.sa_mask);
-
act.sa_flags=0;
-
act.sa_handler=sig_int;
-
sigaction(SIGINT,&act,&old_act);
-
-
if((pid=fork()) <0)
-
printf("fork() error\n");
-
else if(pid == 0) {
-
printf("pid in chlid =%d\n",getpid());
-
sigemptyset(&act.sa_mask);
-
act.sa_flags=0;
-
act.sa_handler=sig_child_exit;
-
sigaction(SIGUSR1,&act,&old_act);
-
kill(getpid(),SIGUSR1);
-
alarm(2);
-
printf("----------\n");
-
sleep_time=sleep(20);
-
printf("+++++sleep_time=%d+++++++\n",sleep_time);
-
exit(0);
-
}
-
wait(&status);
-
-
printf("parent id =%d,status=[%d]\n",getpid(),status);
-
-
return 0;
-
}
编译运行:
gwwu@hz-dev2.wgw.com:~/test/process>gcc -g signal.c -o a
gwwu@hz-dev2.wgw.com:~/test/process>./a
pid in chlid =6675
sig child exit pid=6675,ppid=6674 ///子进程运行了自己定义的信号处理函数,覆盖了父进程的信号处理函数
----------
sig alrm pid=6675,ppid=6674
+++++sleep_time=18+++++++
parent id =6674,status=[0]
另外如果是外部进程传入的信号,父子进程同时相应。
-
#include <unistd.h>
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <signal.h>
-
static void sig_exit()
-
{
-
printf("sig exit pid=%d,ppid=%d\n",getpid(),getppid());
-
}
-
-
static void sig_alrm()
-
{
-
printf("sig alrm pid=%d,ppid=%d\n",getpid(),getppid());
-
}
-
static void sig_int()
-
{
-
printf("sig int pid=%d,ppid=%d\n",getpid(),getppid());
-
}
-
static void sig_child_exit()
-
{
-
printf("sig child exit pid=%d,ppid=%d\n",getpid(),getppid());
-
}
-
-
int main()
-
{
-
pid_t pid;
-
int status;
-
int sleep_time=0;
-
struct sigaction act,old_act;
-
-
sigemptyset(&act.sa_mask);
-
act.sa_flags=0;
-
act.sa_handler=sig_exit;
-
sigaction(SIGUSR1,&act,&old_act);
-
-
-
act.sa_handler=sig_alrm;
-
act.sa_flags=0;
-
sigemptyset(&act.sa_mask);
-
sigaction(SIGALRM,&act,&old_act);
-
-
sigemptyset(&act.sa_mask);
-
act.sa_flags=0;
-
act.sa_handler=sig_int;
-
sigaction(SIGINT,&act,&old_act);
-
-
if((pid=fork()) <0)
-
printf("fork() error\n");
-
else if(pid == 0) {
-
printf("pid in chlid =%d\n",getpid());
-
sigemptyset(&act.sa_mask);
-
act.sa_flags=0;
-
act.sa_handler=sig_child_exit;
-
sigaction(SIGUSR1,&act,&old_act);
-
kill(getpid(),SIGUSR1);
-
alarm(10);
-
printf("----------\n");
-
sleep_time=sleep(2);
-
printf("+++++sleep_time=%d+++++++\n",sleep_time);
-
exit(0);
-
}
-
wait(&status);
-
-
printf("parent id =%d,status=[%d]\n",getpid(),status);
-
-
return 0;
-
}
编译运行:
gwwu@hz-dev2.wgw.com:~/test/process>./a
pid in chlid =6695
sig child exit pid=6695,ppid=6694
----------
^Csig int pid=6695,ppid=6694 ////Ctrl+C 中断, 发现父子进程都会对SIGINT信号进行处理
+++++sleep_time=1+++++++
sig int pid=6694,ppid=32689
parent id =6694,status=[0]
阅读(1103) | 评论(0) | 转发(0) |