每个进程都有与其相关的所谓 信号屏蔽 ,它定义了被 阻塞
的信号集。可以查询信号掩码或使用
setprocmask(2)(对于单线程代码)和
pthread_sigmask(3)(对于多线程代码)进行设置。
每当发出信号时(显式地通过
kill(2)或
raise(3),或通过某种其他机制,例如分段故障升高
SIGSEGV),都会根据当前信号掩码检查信号。如果未阻塞信号,则立即采取行动:如果设置了相应的信号处理程序,则将运行默认操作(通常以异常状态退出或忽略它)。如果信号被信号掩码阻止,则信号状态将设置为
待处理 ,程序将继续执行。
因此,请考虑以下示例程序:
#include <signal.h>#include <stdio.h>void on_sigusr1(int sig){ // Note: Normally, it's not safe to call almost all library functions in a // signal handler, since the signal may have been received in a middle of a // call to that function. printf("SIGUSR1 received!n");}int main(void){ // Set a signal handler for SIGUSR1 signal(SIGUSR1, &on_sigusr1); // At program startup, SIGUSR1 is neither blocked nor pending, so raising it // will call the signal handler raise(SIGUSR1); // Now let's block SIGUSR1 sigset_t sigset; sigemptyset(&sigset); sigaddset(&sigset, SIGUSR1); sigprocmask(SIG_BLOCK, &sigset, NULL); // SIGUSR1 is now blocked, raising it will not call the signal handler printf("about to raise SIGUSR1n"); raise(SIGUSR1); printf("After raising SIGUSR1n"); // SIGUSR1 is now blocked and pending -- this call to sigwait will return // immediately int sig; int result = sigwait(&sigset, &sig); if(result == 0) printf("sigwait got signal: %dn", sig); // SIGUSR1 is now no longer pending (but still blocked). Raise it again and // unblock it raise(SIGUSR1); printf("about to unblock SIGUSR1n"); sigprocmask(SIG_UNBLOCK, &sigset, NULL); printf("Unblocked SIGUSR1n"); return 0;}输出:
SIGUSR1 received!about to raise SIGUSR1After raising SIGUSR1sigwait got signal: 30about to unblock SIGUSR1SIGUSR1 received!Unblocked SIGUSR1



