Unix环境高级编程(阅读笔记)----信号集、信号屏蔽函数sigprocmask

来源:互联网 发布:华为云与阿里云区别 编辑:程序博客网 时间:2024/04/30 09:58

信号屏蔽字是指一个进程中当前阻塞而不能够递送给该进程的信号集。

信号集则是一个能表示多个信号的集合的一种数据类型,为sigset_t

与信号集设置相关的函数有如下几个:

//  下列四个函数成功返回0,出错返回-1 

int sigemptyset(sigset_t *set);  

int sigfillset(sigset_t *set);  

int sigaddset(sigset_t *set, int signo);  

int sigdelset(sigset_t *set, int signo);  

 

/* 

 * 下面函数若真返回1,若假返回0,出错返回-1 

 */  

int sigismember(const sigset_t *set, int signo);  

要注意的是,所有应用程序在使用信号集前,要对信号集调用sigemptysetsigfillset一次。这是因为C编译器把未赋初值的外部和静态变量都初始化为0,而这是否与给定的信号集实现对应却并不清楚

设置信号屏蔽字则要调用下面函数:

int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oset);
how
取值有下列三个

SIG_BLOCK set中包含的是希望阻塞的附加信号

SIG_UNBLOCKset中包含的是希望解除阻塞的信号

SIG_SETMASKset中包含的是现有屏蔽字的代替值

oset是非空指针,则返回进程的当前信号屏蔽字。

set为空,则进程信号屏蔽字不变,how值无意义。

另外,注意一点,不可以阻塞SIGKILLSIGSTOP信号。

要想处理关于信号屏蔽字的问题,还需要一个函数,就是sigpending,原型如下:

int sigpending(sigset_t *set);


此函数通过
set返回当前正在阻塞的信号的信号集。

CTRL+C--->SIGINT

CTRL+Z---->SIGTSTP

CRL+/----->SIGQUIT

下面通过一个实例理解一下这几个函数的用法:

1.   #include <stdio.h>  

2.   #include <stdlib.h>  

3.   #include <unistd.h>  

4.   static void sig_quit(int);  

5.    static void err_quit(const char *str)  

6.   {  

7.       perror(str);  

8.       exit(-1);  

9.   }  

10.    int main(void)  

11.  {  

12.       sigset_t newmask, oldmask, pendmask;  

13.         if (signal(SIGQUIT, sig_quit) == SIG_ERR)  

14.          err_quit("can't catch SIGQUIT");  

15.      sigemptyset(&newmask);  

16.       sigaddset(&newmask, SIGQUIT);  

17.      if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)  

18.           err_quit("SIG_BLOCK error");  

19.         sleep(5);  

20.        if (sigpending(&pendmask) < 0)  

21.          err_quit("sigpending error");  

22.       if (sigismember(&pendmask, SIGQUIT))  

23.          printf("\nSIGQUIT pending\n");  

24.      if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)  

25.           err_quit("SIG_SETMASK error");  

26.      printf("SIGQUIT unblocked\n");  

27.        sleep(5);  

28.       exit(0);  

29.  }  

30.    static void sig_quit(int signo)  

31.   {  

32.      printf("caught SIGQUIT\n");  

33.       if (signal(SIGQUIT, SIG_DFL) == SIG_ERR)  

34.          err_quit("can't reset SIGQUIT");  

35.   }  


在ubuntu12.04下运行结果如下

[unix]$ ./a.out 
^\^\^\^\^\^\^\^\^\^\
SIGQUIT pending
caught SIGQUIT
SIGQUIT unblocked
^\退出 (核心已转储)

0 0
原创粉丝点击