回想10.8节一个进程的信号掩码是当前阻塞而不能分发给进程的信号集。一个进程可以检查它的信号掩码,改变它的信号掩码,或通过调用下面的函数在一个步骤里执行两个操作。
- #include <signal.h>
- int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oset);
- 成功返回0,错误返回-1
首先,如果oset是一个非空指针,进程的当前信号掩码通过oset返回。
其次,如果set是一个非空指针,那么how参数指出当前信号掩码如何被修改。下表描述了how的可能值。SIG_BLOCK是非互斥的或操作,而SIG_SETMASK是一个赋值。注意SIGKILL和SIGSTOP不能被阻塞。
使用sigprocmask改变当前信号掩码的方法how | 描述 |
---|
SIG_BLOCK | 进程的新信号掩码是它当前掩码和set指向的信号集的并集,也就是说,set包含了我们想阻塞的额外的信号。 |
SIG_UNBLOCK | 进程的信号掩码是当前信号掩码和set指向的信号集的反码的交集。也就是说,集合包含了我们想反阻塞的信号。 |
SIG_SETMASK | 进程的新信号掩码被set指向的信号集的指代替。 |
如果set是一个空指针,进程的信号掩码不变,而how被忽略。
在调用sigprocmask后,如果任何反阻塞的信号在待定,那么这些信号里至少有一个在sigprocmask返回前被分发给进程。
sigprocmask函数只为单线程进程定义。另一个函数被提供以在多线程进程里执行一个线程信号掩码。我们将在12.8节讨论这个。
下面的代码展示了一个打印调用进程的信号掩码里的信号名:
- #include <errno.h>
- #include <signal.h>
- void
- pr_mask(const char *str)
- {
- sigset_t sigset;
- int errno_save;
- errno_save = errno; /* we can be called by signal handlers */
- if (sigprocmask(0, NULL, &sigset) < 0) {
- printf("sigprocmask error\n");
- exit(0);
- }
- printf("%s", str);
- if (sigismember(&sigset, SIGINT)) printf("SIGINT ");
- if (sigismember(&sigset, SIGQUIT)) printf("SIGQUT ");
- if (sigismember(&sigset, SIGUSR1)) printf("SIGUSR1 ");
- if (sigismember(&sigset, SIGALRM)) printf("SIGALRM ");
- /* remaining signals can go here */
- printf("\n");
- errno = errno_save;
- }
我们将在本章后面使用这个函数。为了节省空间,我们没有测试10.2节列出的所有信号。
阅读(984) | 评论(0) | 转发(0) |