sigaction函数
修改信号处理动作(通常在Linux用其来注册一个信号的捕捉函数)
;失败:-1,设置errno
参数:
act:传入参数,新的处理方式。oldact:传出参数,旧的处理方式。
struct
sigaction结构体
struct
sigaction {
void(*sa_handler)(int);
void(*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void(*sa_restorer)(void);
};
sa_restorer:该元素是过时的,不应该使用,POSIX.1标准将不指定该元素。(弃用)
sa_sigaction:当sa_flags被指定为SA_SIGINFO标志时,使用该信号处理程序。(很少使用)
重点掌握:
① sa_handler:指定信号捕捉后的处理函数名(即注册函数)。也可赋值为SIG_IGN表忽略
或 SIG_DFL表执行默认动作
② sa_mask: 调用信号处理函数时,所要屏蔽的信号集合(信号屏蔽字)。注意:仅在处理函数被调用期间屏蔽生效,是临时性设置。用sigaddset函数添加需要被捕捉的信号。
,表使用默认属性:为0的时候,可以屏蔽正在处理的信号(若在处理2号信号时又有2号信号,则此时传来的2号信号会被屏蔽)。
不多说了,上代码:
#include
<stdlib.h>
#include
<stdio.h>
#include
<signal.h>
void func(int
signal)
{
printf("%d号信号被捕捉。\n", signal);
}
int main(void)
{
struct
sigaction act, oldact;
act.sa_handler = func;
act.sa_flags = 0;//为0的时候,可以屏蔽正在处理的信号(若在处理2号信号时又有2号信号,则>会被屏蔽)
sigemptyset(&act.sa_mask);//sa_mask是一个临时信号集,将其清零(初始化I)
sigaddset(&act.sa_mask, SIGQUIT);//将3号信号添加到信号集,即:3号信号就是我们在处理2号信号的时候需要屏蔽的那个信号,也许可以添加其他信号,比如20号信号
sigaddset(&act.sa_mask, SIGTSTP);
int s_ret = sigaction(SIGINT, &act, &oldact);
if (0>s_ret)
{
perror("sigaction error");
exit(1);
}
while (1);
return 0;
}
号信号。所以在我按下ctrl+\之后并没有反应,程序依旧执行,但是在真正的Linux独立系统中,按下之后该程序会被杀掉的,就如同我按下ctrl+z之后,程序挂起:接下来kill掉就是了。
———————————————隔了不到十分钟又来更新的分割线——————————————-
我们来看看信号捕捉特性
进程正常运行时,默认PCB中有一个信号屏蔽字,假定为☆,它决定了进程自动屏蔽哪些信号。当注册了某个信号捕捉函数,捕捉到该信号以后,要调用该函数。而该函数有可能执行很长时间,在这期间所屏蔽的信号不由☆来指定。而是用sa_mask来指定。调用完信号处理函数,再恢复为☆。
XXX信号捕捉函数执行期间,XXX信号自动被屏蔽。
个实时信号支持排队)
所说的内容,我们这样改代码:
void func(int
signal)
{
printf("%d号信号被捕捉。\n", signal);
sleep(5);//睡眠十秒,模拟处理信号的函数处理时间很长的那种情况
puts("———————————— - fiish———————");
}
我的测试结果:
翻转为1,信号集是什么?是位图。他不能为多次的相同的信号计数。所以,再多的相同信号在系统看来也只是一个罢了。
————————————–再更新一次————————————-
signal()和sigaction()函数是捕捉信号的函数么?是么?是么?是么?
不是,他俩只是注册信号捕捉函数的函数,真正动手捉信号的是内核。记得啊。本质区别的。