linux信号处理四(sigaction参数说明)
sigaction函数的功能是检查或修改与指定信号相关联的处理动作(可同时两种操作)。
他是POSIX的信号接⼝,⽽signal()是标准C的信号接⼝(如果程序必须在⾮POSIX系统上运⾏,那么就应该使⽤这个接⼝)
给信号signum设置新的信号处理函数act,同时保留该信号原有的信号处理函数oldact
int sigaction(int signo,const struct sigaction *restrict act,
struct sigaction *restrict oact);
第⼆、第三个参数为,sigaction结构类型定义如下:
struct sigaction{
void (*sa_handler)(int);
sigset_t sa_mask;
int sa_flag;
void (*sa_sigaction)(int,siginfo_t *,void *);
};
sa_handler:字段包含⼀个信号捕捉函数的地址
sa_mask:字段说明了⼀个信号集,在调⽤该信号捕捉函数之前,这⼀信号集要加进进程的信号屏蔽字中。
    即执⾏信号处理函数期间,阻塞信号屏蔽字中的信号,执⾏结束后再处理这期间发⽣的信号(sa_mask集中的信号)。注:阻塞的意思是延迟相应信号
sa_flag :是⼀个选项,注意:这个选项只与sigaction函数注册的信号有关联,与sa_mask中的信号⽆任何关系。
SA_INTERRUPT 由此信号中断的系统调⽤不会⾃动重启
SA_RESTART 由此信号中断的系统调⽤会⾃动重启
SA_SIGINFO 提供附加信息,⼀个指向siginfo结构的指针以及⼀个指向进程上下⽂标识符的指针
SA_NODEFER ⼀般情况下,当信号处理函数运⾏时,内核将阻塞(sigaction函数注册时的信号)。但是如果设置了SA_NODEFER标
记,那么在该信号处理函      数运⾏时,内核将不会阻塞该信号。
SA_RESETHAND  当调⽤信号处理函数时或信号处理函数结束后,将信号的处理设置为系统默认值。
最后⼀个参数是⼀个替代的信号处理程序,当设置SA_SIGINFO时才会⽤他。
例⼦:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void show_handler(int sig)
{
printf("I got signal %d\n", sig);
linux下的sleep函数
int i;
for(i = 0; i < 5; i++)
{
printf("i = %d\n", i);
sleep(1);
}
}
int main(void)
{
int i = 0;
struct sigaction act, oldact;
act.sa_handler = show_handler;
sigaddset(&act.sa_mask, SIGQUIT); //见注(1)
act.sa_flags = SA_RESETHAND | SA_NODEFER; //见注(2)
//act.sa_flags = 0; //见注(3)
sigaction(SIGINT, &act, &oldact);
while(1)
{
sleep(1);
printf("sleeping %d\n", i);
i++;
}
}
注:
(1)    如果在信号SIGINT(Ctrl + c)的信号处理函数show_handler执⾏过程中,本进程收到信号SIGQUIT(Crt+\),将阻塞该信号,直到
show_handler执⾏结束才会处理信号SIGQUIT。
(2)    SA_NODEFER⼀般情况下,当信号处理函数运⾏时,内核将阻塞<;该给定信号 -- SIGINT>。但是如果设置了SA_NODEFER标记,那么在该信号处理函数运⾏时,内核将不会阻塞该信号。 SA_NODEFER是这个标记的正式的POSIX名字(还有⼀个名字
SA_NOMASK,为了软件的可移植性,⼀般不⽤这个名字)
SA_RESETHAND当调⽤信号处理函数时,将信号的处理函数重置为缺省值。 SA_RESETHAND是这个标记的正式的POSIX名字(还有⼀个名字SA_ONESHOT,为了软件的可移植性,⼀般不⽤这个名字)
(3)    如果不需要重置该给定信号的处理函数为缺省值;并且不需要阻塞该给定信号(⽆须设置sa_flags标志),那么必须将sa_flags清零,否则运⾏将会产⽣段错误。但是sa_flags清零后可能会造成信号丢失!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。