Linux信号实践(4)

Sigaction#include <signal.h>int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);

功能:

sigaction函数用于改变进程接收到特定信号后的行为。

参数

第一个参数为信号的值,可以为除SIGKILL及SIGSTOP外的任何一个特定有效的信号(为这两个信号定义自己的处理函数,将导致信号安装错误)

第二个参数是指向结构sigaction的指针,在结构sigaction的实例中,指定了对特定信号的处理,可以为空,进程会以缺省方式对信号处理

第三个参数oldact指向的对象用来保存原来对相应信号的处理,可指定oldact为NULL。

返回值:函数成功返回0,失败返回-1

sigaction结构体

第二个参数最为重要,其中包含了对指定信号的处理、信号所传递的信息、信号处理函数执行过程中应屏蔽掉哪些函数等等

struct sigaction {//信号处理程序 不接受额外数据(比较过时)void (*sa_handler)(int);//信号处理程序能接受额外数据,和sigqueue配合使用(支持信号排队,信号传送其他信息),推荐使用void (*sa_sigaction)(int, siginfo_t *, void *);sigset_t sa_mask; //屏蔽int sa_flags; //表示信号的行为:SA_SIGINFO表示能接受数据void (*sa_restorer)(void); //废弃不用了};//简单示例1: 用sigaction简单替换signal函数void signalAction(int signo, siginfo_t *signalInfo, void *p){cout << "signal = " << signo << ", desc: " << strsignal(signo) << endl;}int main(){struct sigaction act;//注意:回调函数句柄sa_handler、sa_sigaction只能选其一!!!//act.sa_handler = sigHandler;act.sa_sigaction = signalAction;sigemptyset(&act.sa_mask);act.sa_flags = 0;if (sigaction(SIGINT,&act,NULL) == -1)err_exit("sigaction error");pause();}//简单实例2: 用sigaction模拟signal函数sighandler_t mySignal(int signum, sighandler_t handler){struct sigaction act;struct sigaction oldAct;act.sa_handler = handler;sigemptyset(&act.sa_mask);act.sa_flags = 0;if (sigaction(signum, &act, &oldAct) == -1)return SIG_ERR;return oldAct.sa_handler;}

sa_mask选项

sa_maskspecifiesamaskofsignalswhichshouldbeblocked/**指定一个信号集的掩码,在这个掩码中的信号将要阻塞**/ (i.e.,addedtothesignalmaskofthethreadinwhichthesignalhandlerisinvoked)

duringexecutionofthesignalhandler.Inaddition,thesignalwhichtriggeredthehandlerwillbeblocked,

unlesstheSA_NODEFERflagisused.

/**在执行handler的时候,如果此时进程收到了sa_mask所包含的信号,则这些信号将不会被响应,直到handler函数执行完毕

与sigprocmask不同是:sigprocmask是指定该进程的信号屏蔽字->屏蔽该信号,不会接收该信号,而sa_mask则是接收了该信号,但是不会相应该信号**/

//示例: 将sa_mask选项设置以后的效果/** 在进程相应SIGINT信号时, 如果此时有SIGQUIT信号抵达, SIGQUIT信号也不会被响应, 直到SIGINT信号相应完成之后, 才会去相应SIGQUIT信号(如运行截图所示)**/int main(){struct sigaction act;act.sa_handler = sigHandler;sigemptyset(&act.sa_mask);// 添加下面一行后: 在响应SIGINT信号时, 是不会被中断的sigaddset(&act.sa_mask, SIGQUIT);act.sa_flags = 0;if (sigaction(SIGINT, &act, NULL) == -1)err_exit("sigaction error");while (true)pause();}void sigHandler(int signo){cout << "catch a signal, signo = " << signo << ", desc: " << strsignal(signo) << endl;sleep(10);}

//运行截图

sa_flags:详细信息

siginfo_t结构:

siginfo_t{intsi_signo; /* Signal number */intsi_errno; /* An errno value */intsi_code;/* Signal code */intsi_trapno; /* Trap number that causedhardware-generated signal(unused on most architectures) */pid_t si_pid;/* Sending process ID */uid_t si_uid;/* Real user ID of sending process */intsi_status; /* Exit value or signal */clock_t si_utime; /* User time consumed */clock_t si_stime; /* System time consumed */sigval_t si_value; /* Signal value */intsi_int;/* POSIX.1b signal */void *si_ptr;/* POSIX.1b signal */intsi_overrun; /* Timer overrun count; POSIX.1b timers */intsi_timerid; /* Timer ID; POSIX.1b timers */void *si_addr;/* Memory location which caused fault */longsi_band;/* Band event (was int inglibc 2.3.2 and earlier) */intsi_fd;/* File descriptor */short si_addr_lsb; /* Least significant bit of address(since Linux 2.6.32) */}sigqueue#include <signal.h>int sigqueue(pid_t pid, int sig, const union sigval value);

功能

sigqueue是新的发送信号系统调用,主要是针对实时信号提出的支持信号带有参数,与函数sigaction()配合使用。

功夫不负有心人。

Linux信号实践(4)

相关文章:

你感兴趣的文章:

标签云: