Chinaunix首页 | 论坛 | 博客
  • 博客访问: 361886
  • 博文数量: 66
  • 博客积分: 3201
  • 博客等级: 中校
  • 技术积分: 695
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-04 11:17
文章分类

全部博文(66)

文章存档

2016年(1)

2014年(1)

2012年(1)

2011年(2)

2010年(18)

2009年(42)

2008年(1)

分类:

2009-07-19 17:48:02

下面是保护临界区代码不受相关信号干扰的代码片段
---------------------------------------------
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。

阅读(530) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~