/* A `sigset_t’ has a bit for each signal. */
# define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int)))
typedef struct
{
unsigned long int __val[_SIGSET_NWORDS];
} __sigset_t;
用一个位表示一个信号,最多为1024个信号。用位表示可以节省空间,但是设置时就不方便,所以就有一组函数可以方便设置这些位:
sigemptyset(全部置0?)
sigfillset(全部置1?)
sigaddset
sigdelset
sigismember
————————————————————
设置和修改程序的信号接收:
这决定我们程序对系统的信号是处理还是阻塞(不理),注意:是阻塞而不是忽略。两者是不同概念的。
首先有一点要知道:
一个程序默认已经设置了15个信号(进程资源中自动生成一个sigset_t类型空间),而且它们到有了默认的捕获工作函数,有默认的动作。SIGSTOP(19)、SIGKILL(9)这两个信号是不能被修改捕获或忽略的。
上面的那五个函数只是为了我们设置sigset_t,并没有修改进程资源中的sigset_t空间。我们要使用:
sigprocmark(int how,const sigset_t *set,sigset_t * oldset)
进行设置。
这个函数的难点在于明白一点:
sigset_t *set为我们程序中自己定义的空间。
sigset_t * oldset为进程资源中的空间。为了得到上次设置情况而存在的。
要将两者进行比较才能得到要处理的信号。
函数说明 |
sigprocmask()可以用来改变目前的信号遮罩,其操作依参数how来决定 SIG_BLOCK 新的信号遮罩由目前的信号遮罩和参数set 指定的信号遮罩作union,我的理解是oldset和set中设置的信号都被设置(+) SIG_UNBLOCK 将目前的信号遮罩删除掉参数set指定的信号遮罩(-) SIG_SETMASK 将目前的信号遮罩设成参数set指定的信号遮罩(=) 如果参数oldset不是NULL指针,那么目前的信号遮罩会由此指针返回。取得旧数据,sigaction也有这种功能。 |
返回值 |
执行成功则返回0,如果有错误则返回-1。 |
错误代码 |
EFAULT 参数set,oldset指针地址无法存取。 EINTR 此调用被中断 |
———————————————————
设置和修改程序的信号动作:
int sigaction((int signum,const struct sigaction *act ,struct sigaction *oldact);
难理解的地方也在于struct sigaction *oldact。这是为了取得上次对signum设置情况存在的。