一、概述
Linux的系统调用函数sigaction()可以用来查询或设置信号处理方式。
函数声明为:
#include <signal.h>int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
如果执行成功返回0,否则返回-1。其中,参数表示的含义如下:
- signum:要操作的信号,指定除SIGKILL和SIGSTOP以外其所有信号。
- act:要设置的对信号的新处理方式,sigaction指针结构体
- 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);
}
在sigaction结构体中,参数表述如下:
- sa_handler:函数指针,指向一个信号处理函数
- sa_sigaction:获得关于信号的更详细信息
- sa_flags:成员的值包含SA_SIGINFO时,系统将使用sa_sigaction函数作为信号处理函数,否则使用sa_handler
- sa_mask:用来指定在信号处理函数执行期间需要被屏蔽的信号,信号自身会被自动放入进程的信号掩码,不会重复执行
sa_flags成员用于指定信号的处理行为,它可以是以下值的“按位或”组合。
- SA_RESTART:使被信号打断的系统调用自动重新发起
- SA_NOCLDSTOP:使父进程在它的子进程暂停或继续运行时不会收到SIGCHLD信号
- SA_NOCLDWAIT:使父进程在它的子进程退出时不会收到SIGCHLD信号,这时子进程如果也退出,也不会成为僵尸进程
- SA_NODEFER:使对信号的屏蔽无效,即在信号处理函数执行期间,仍能发出这个信号
- SA_RESETHAND:信号处理之后重新设置为默认的处理方式
- SA_SIGINFO:使用sa_sigaction作为默认的信号处理函数
二、sigaction使用示例
#include <stdio.h>
#include <unistd.h>
#include <signal.h>static void sig_usr(int signum)
{if(signum == SIGUSR1){printf("SIGUSR1 received \n");}else{printf("signal %d received\n",signum);}
}
int main(void)
{struct sigaction sa_usr;sa_usr.sa_flags = 0;sa_usr.sa_handler = sig_usr;//管理信号处理函数sigcation(SIGUSR1,&sa_usr,NULL);//注册信号处理方式printf("PID = %d\n",getpid());//打印当前进程pidwhile(1){//等待外部kill 当前进程}return 0;
}
保存文件,编译当前文件并执行:
# g++ testMysigcation.cpp -o run
# ./run PID = 42273
现在打开另一个终端,用kill发送命令:
# kill -USR1 42273SIGUSR1 received
可见sig_usr接收到了发送的信号,并正确打印了结果。sigaction注册信号处理函数时,不会自动重新发起被信号打断的系统调用。
------分享知识,让人愉悦,原创博文,支持请点赞。