曲径通幽论坛

标题: sigset() -- sinal 的可靠对应函数 [打印本页]

作者: beyes    时间: 2009-7-25 04:07
标题: sigset() -- sinal 的可靠对应函数
sigset()函数是 signal()函数的可靠对应函数,其声明为:
#include <signal.h>

typedef void (*sighandler_t)(int);

sighandler_t sigset(int sig, sighandler_t disp);
sigset() 函数将 sig 指定的信号部署改为 disp 指定的部署。disp 参数还可以是以下 4 个值中的一个:
注意:这里的几个常量里, SIG_HOLD 特殊些,这个是 UNIX 里定义的常量。默认情况下,是不定义这个常量的。这个常量定义在 /usr/include/bits/signum.h 中:
#ifdef __USE_UNIX98
# define SIG_HOLD       ((__sighandler_t) 2)    /* Add signal to hold mask.  */
#endif
可见,需要定义宏 __USE_UNIX98 后才能直接使用到这个常量。而出现在/usr/include/features.h 头文件中的这个 __USE_UNIX98 宏默认是 #undef 的,这留给使用者自行定义。所以,为了使用这个常量,在当前目录下添加一个头文件:
unix98.h
在里头添加一句:
#define    __USE_UNIX98
这样定义后,在下面的测试程序中就可以直接使用到这个常量,否则会在编译时报告变量未定义。

测试程序
#include <stdio.h>
#include <unistd.h>
#include "unix98.h"
#include <signal.h>

static volatile sig_atomic_t sig;
static void sigusr(int sig_num);

int main(void)
{

    if (sigset(SIGUSR1, SIG_HOLD) == SIG_ERR)
        printf("Can't catch SIGUSR1");
    if (sigset(SIGUSR2, sigusr) == SIG_ERR)
        printf("Can't catch SIGUSR2");

    for(;;) {
       pause();
       if (sig == SIGUSR1)
        printf("Received SIGUSR1\n");
       else
        printf("Received SIGUSR2\n");
    }
}

static void sigusr (int sig_num)
{
    if ((sig_num == SIGUSR1) || (sig_num == SIGUSR2))
        sig = sig_num;
    else
        printf("Received signal %d", sig_num);
}
编译程序时,会对 SIG_ERR 常量发出警告,因为整型量和指针型量是不匹配的。但是在函数调用出错时,返回的是整型量(-1)。所以,对这个编译警告可以不予理会。
运行程序后,在另外一个终端里输入:
beyes@linux-beyes:~/C/signal> kill -USR1 9358
beyes@linux-beyes:~/C/signal> kill -USR2 9358
beyes@linux-beyes:~/C/signal> kill -USR2 9358
在程序运行的窗口里,可以看到,对于 SIGUSR1 信号不予理会,因为这已经被加入到了信号掩码中。而 SIGUSR2 会被捕捉到并被处理:
beyes@linux-beyes:~/C/signal> ./sigset2.exe
Received SIGUSR2
AReceived SIGUSR2

sig 变量为全局变量,被定义为 static volatile sig_atomic_t 类型。由于 sig 会被至少两个不同的控制线程访问: main() 函数和异步的信号处理程序,所以也总将 volatitle 类型限定符用于 sig 面前。

ISO C 将 sig_atomoc_t 定义为整型对象,可以作为原子实体对其进行访问,即使存在异步中断。这意味着必须使用一种机器指令访问这种类型变量,并且这种变量不可以扩展到跨越页面边界。




欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) Powered by Discuz! X3.2