lienhua34 1 信号传递过程信号源为目标进程产生了一个信号,然后由内核来决定是否要将该信号传递给目标进程。从信号产生到传递给目标进程的流程图如图 1 所示, 图 1: 信号产生、传递到处理的流程图 进程可以阻塞信号的传递。当信号源为目标进程产生了一个信号之后,内核会执行依次执行下面操作, 1. 如果目标进程设置了忽略该信号,则内核直接将该信号丢弃。 2. 如果目标进程没有阻塞该信号,则内核将该信号传递给目标进程,由目标进程执行相对应操作。 3. 如果目标进程设置阻塞该信号,则内核将该信号放到目标进程的阻塞信号列表中,等待目标进程对该类型信号的下一步设置。若目标进程后续设置忽略该信号,则内核将该信号从目标进程的阻塞信号列表中移除并丢弃。若目标进程对该信号解除了阻塞,内核将该信号传递给目标进程进行相对应的操作。 在信号产生到信号传递给目标进程之间的时间间隔内,我们称该信号为未决的(pending)。 每个进程都有一个信号屏蔽字(signal mask),它规定了当前要阻塞传递给该进程的信号集。对于每种可能的信号,信号屏蔽字中都有一位与之对应。 2 信号集及其操作POSIX.1 定义了一个数据类型sigset_t,用于表示信号集。另外,头文件 signal.h 提供了下列五个处理信号集的函数。 函数 sigemptyset 初始化由 set 指向的信号集,清除其中所有信号。
函数 sigfillset 初始化由 set 指向的信号集,使其包含所有信号。
函数 sigaddset 将一个信号 signo 添加到现有信号集 set 中。
函数 sigdelset 将一个信号 signo 从信号集 set 中删除。
函数 sigismember 判断指定信号 signo 是否在信号集 set 中。
3. sigprocmask 检 或设置进程的信号屏蔽字调用 sigprocmask 函数可以检测或者设置进程的信号屏蔽字。
若 oset 参数是一个非空指针,则进程的当前信号屏蔽字将通过 oset 返回。若 set 参数是一个非空指针,则参数 how 将指示如何修改当前信号屏蔽字。how 的可选值如表 1 所示,
下面我们来看一个例子。在下面的程序文件中先调用 sigprocmask 设置阻塞信号 SIGALRM,然后调用 alarm(2) 设置一个两秒钟的闹钟(两秒钟之后将向当前进程产生一个 SIGALRM 信号)。在睡眠 4 秒钟之后(此时应该已经产生了 SIGALRM 信号),调用 sigprocmask 函数解除对信号SIGALRM 的阻塞。
sigprocmaskdemo.c
编译该程序文件 sigprocmaskdemo.c,生成并执行文件 sigprocmaskdemo, lienhua34:demo$ gcc -o sigprocmaskdemo sigprocmaskdemo.c
lienhua34:demo$ ./sigprocmaskdemo
before unblock sigprocmask
received SIGALRM
before exit
从上面的执行输出,我们看到信号 SIGALRM 是在调用 sigprocmask函 数 执 行 unblock 之 后 才 被 传 递 给 当 前 进 程 进 行 处 理 的。 如 果 我 们 将sigprocmaskdemo.c 中的sigprocemask(SIG_BLOCK, &sigset, NULL) 注释掉,编译执行,生成如下结果, lienhua34:demo$ ./sigprocmaskdemo received SIGALRM before unblock sigprocmask before exit 4 sigpending 获取进程未决的信号集函数 sigpending 获取当前进程所有未决的信号。通过其 set 参数返回未决的信号集。
下面我们来看一个例子,
sigpendingdemo.c
编译该程序 sigpendingdemo.c,生成并执行文件 sigpendingdemo。从下面的运行结果,我们看到调用 alarm 函数产生信号 SIGALRM 之后,该信号在 sigpending 函数的 set 参数指向的信号集中。 lienhua34:demo$ gcc -o sigpendingdemo sigpendingdemo.c
lienhua34:demo$ ./sigpendingdemo
before alarm: SIGALRM is not pending
after alarm: SIGALRM is pending
(done) |
|
来自: 戴维图书馆 > 《UNIX环境高级编程》