信号是由UNIX和LINUX系统响应某些条件而产生的一个事件。接收到该信号的进程会相应地采取一些行动。
按照下面给出的代码,用sigaction来截获SIGINT信号(Ctrl+Z)。
2#include <stdio.h>
3#include <unistd.h>
4void ouch(int sig)
5{
6 printf("OUCH! I got signal %d\n",sig);
7}
8
9int main()
10{
11 struct sigaction act;
12 act.sa_handler = ouch;
13 sigemptyset(&act.sa_mask);
14 sigfillset(&act.sa_mask);
15 act.sa_flags = 0;
16
17 sigaction(SIGINT,&act,0);
18
19 while(1)
20 {
21 printf("Hello World!\n");
22 sleep(1);
23 }
24}
其中的sigaction函数的定义如下:
/**
** 第一个参数为捕获的信号;
** 第二个参数指向一个结构,该结构的作用是定义在
接收到信号后应该采取的行动;
** 第三个参数我也不知道有啥用,反正一般都设为空,
如果不是空的话,将把原先对该信号的动作写到它
指向的位置。
**/
再来看看第二个参数指向的结构的具体内容:
struct sigaction
{
void (*) (int) sa_handler /*function,SIG_DEL or SIG_IGN
sigset_t sa_mask /* signals to block in sa_handler
int sa_flags /* signal action modifiers
}
改结构中的第三项,sa_flags字段,可以包含下表中的取值,它们用于改变信号的行为。
------------------------------------------------------------------------------
SA_NOCLDSTOP 子进程停止时不产生SIGCHLD信号
SA_PESETHAND 将对此信号的处理方式在信号处理函数的入口处重置为SIG_DFL
SA_RESTART 重启可中断的函数而不是给出EINTR错误
SA_NODEFER 捕获到信号时不将它添加到信号屏蔽字中
------------------------------------------------------------------------------
几个常用的处理信号的函数:
int sigaddset (sigset_t *set, int signo);
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigdelset(sigset_t *set, int signo);
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
int sigsuspend(const sigset_t *sigmask);
sigprocmask函数可以根据参数how指定的方法对进程的信号屏蔽字进行修改。参数how的取值如下:
-------------------------------------------------------------------------------
SIG_BLOCK 把参数set中的信号添加到信号屏蔽字中
SIG_SETMASK 把信号屏蔽字设置为参数set中的信号
SIG_UNBLOCK 从信号屏蔽字中删除参数set中的信号
-------------------------------------------------------------------------------
sigsuspend函数将进程的屏蔽字替换为由参数sigmask给出的信号集,然后挂起程序的执行。