下面是保护临界区代码不受相关信号干扰的代码片段
---------------------------------------------
sigprocmask(SIG_BLOCK, &newmask, &oldmask);
Critical region
sigsuspend(&waitmask);
sigprocmask(SIG_SETMASK, &oldmask, NULL);
---------------------------------------------
man sigsuspend:
1.sigsuspend() temporarily replaces the signal mask of the calling process;
2.and then suspends the process
3.then sigsuspend() returns after the signal handler returns;
4.and the signal mask is restored to the state before the call to sigsuspend().
分析代码
============================
#include "apue.h"
static void sig_int(int);
int
main(void)
{
sigset_t newmask, oldmask, waitmask;
pr_mask("program start: ");
if (signal(SIGINT, sig_int) == SIG_ERR)
err_sys("signal(SIGINT) error");
sigemptyset(&waitmask);
sigaddset(&waitmask, SIGUSR1);
sigemptyset(&newmask);
sigaddset(&newmask, SIGINT);
/*
* Block SIGINT and save current signal mask.
*/
if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
err_sys("SIG_BLOCK error");
/*
* Critical region of code.
*/
pr_mask("in critical region: ");
/*
* Pause, allowing all signals except SIGUSR1.
*/
if (sigsuspend(&waitmask) != -1)
err_sys("sigsuspend error");
pr_mask("after return from sigsuspend: ");
/*
* Reset signal mask which unblocks SIGINT.
*/
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
err_sys("SIG_SETMASK error");
/*
* And continue processing ...
*/
pr_mask("program exit: ");
exit(0);
}
static void
sig_int(int signo)
{
pr_mask("\nin sig_int: ");
}
=================================================
打印出
program start:
in critical region: SIGINT
^C
in sig_int: SIGINT SIGUSR1
after return from sigsuspend: SIGINT
program exit:
可见:在调用sigsuspend之前只有SIGINT被阻塞,调用sigsuspend后,信号屏蔽字集被临时替换成SIGUSR1,此时可以递送SIGINT,当SIGINT发生,去执行sig_int,注意:在sig_int里会打出
in sig_int: SIGINT SIGUSR1 ,是因为操作系统会自动给正在被递送的信号加入屏蔽字集里,当sig_int返回,sigsuspend也将返回,此时屏蔽字就是SIGINT。
阅读(573) | 评论(0) | 转发(0) |