Linux信号 五 信号挂起与信号掩码操作接口集

    A signal may be blocked, which means that it will not be delivered
until it is later unblocked.  Between the time when it is generated
and when it is delivered a signal is said to be pending.
    信号可以被阻塞,除非阻塞被解除否则不能将信号传递给进程。从信号产生到信号被解除
阻塞这一段时间称之为挂起。
    Each thread in a process has an independent signal mask, which
indicates the set of signals that the thread is currently blocking.
    进程内的每个线程都有一个独立的信号掩码,信号掩码是一组信号集合,表明当前线程
阻塞的信号。

Linux提供了一个新的数据结构用来实现信号掩码的功能:信号集。多个信号组成的集合被称为信号集,其数据类型为sigset_t。在Linux的实现中,sigset_t类型是位掩码,每一个比特代表一个信号。

相关操作接口包括信号集初始化、添加、删除、设置信号掩码等:

sigemptyset,  sigfillset,  sigaddset,  sigdelset, sigismember
sigprocmask, pthread_sigmask

#include <signal.h>

/**
 *  初始化一个空的未包含任何信号的信号集。
 *  成功返回0,失败返回-1并置errno 
 */
int sigemptyset(sigset_t *set);

/**
 *  初始化一个包含任何信号的信号集。
 *  成功返回0,失败返回-1并置errno 
 */
int sigfillset(sigset_t *set);

/**
 *  向信号集中添加一个信号。
 *  成功返回0,失败返回-1并置errno 
 */
int sigaddset(sigset_t *set, int signum);


/**
 *  从信号集中删除一个信号。
 *  成功返回0,失败返回-1并置errno 
 */
int sigdelset(sigset_t *set, int signum);


/**
 *  判断该信号是否在信号集中
 *  属于返回1,不属于返回0,出错返回-1并置errno
 */
int sigismember(const sigset_t *set, int signum);

/**
 *  将当前线程的信号集读取到set结构体中
 *  成功返回0,失败返回-1并置errno
 */
int sigpending(sigset_t *set);


Glibc扩展函数
如果定义了 _GNU_SOURCE 宏,signal.h还提供了额外三个参数用于操作信号集,不过
这些都是非标准的函数(其它系统可能有类似的实现),不能用于移植程序的开发中

/**
 *  判断信号集是否为空
 *  为空返回1,否则返回0
 */
int sigisemptyset(const sigset_t *set);

/**
 *  取left 和 right的并集,并存储到dest结构体中
 *  成功返回0,失败返回-1并置errno
 */
int sigorset(sigset_t *dest, const sigset_t *left,
                     const sigset_t *right);
/**
 *  取left 和 right的交集,并存储到dest结构体中
 *  成功返回0,失败返回-1并置errno
 */
int sigandset(sigset_t *dest, const sigset_t *left,
                     const sigset_t *right);

/**
 *  获取或设置进程的阻塞信号掩码
 *
 *  根据参数how的值,提供了三种用于改变进程的阻塞信号掩码方式
 *
 *  SIG_BLOCK:新的进程信号掩码是当前信号掩码与set指向信号集的并集,相当于在当前信号集
 *  掩码中增加set的信号。
 *
 *  SIG_UNBLOCK: 新的进程信号掩码是当前信号掩码与set指向信号集的补集的交集,相当于从
 *  当前信号掩码中删除set中信号,解除对其的屏蔽。
 *
 *  SIG_SETMASK : 直接把进程的信号掩码设置成set指向的信号集。
 *
 *  如果参数oldset不为NULL,之前的信号掩码配置将会存储到该指针中。
 *  如果参数set为NULL的话,相当于不做任何改变。
 *
 *  另外多线程中使用该函数的结果将是未定义的,多线程中最好使用pthread_sigmask()接口
 *
 *  成功返回0,失败返回-1并置errno
 */
#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

/**
 *  该函数功能和sigprocmask一样,只不过是用在多线程中,用于改变调用线程的信号掩码集。
 *  
 *  成功返回0,失败返回错误码,编译链接的时候加上-pthread选项。
 */
#include <signal.h>
int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset);

参考资料

1. 《Linux环境编程,从应用到内核》高峰,李彬著

2. man signal : http://www.man7.org/linux/man-pages/man7/signal.7.html

    man sigsetops : http://www.man7.org/linux/man-pages/man3/sigsetops.3.html

猜你喜欢

转载自blog.csdn.net/fuyuande/article/details/83927235