免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1654 | 回复: 0
打印 上一主题 下一主题

APUE学习笔记之:sigsuspend函数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-12-27 22:14 |只看该作者 |倒序浏览

                                                                                                1.函数原型
               
               
                #include signal.h>
int sigsuspend(const sigset_t *sigmask);
                                   
返回值:-1,并将errno设置为 EINTR
    sigsuspend 函数将进程的信号屏蔽字设置为 sigmask 指向的值。在捕捉到一个信号或发生了一个会终止该进程的信号之前,该进程被挂起。如果捕捉到一个信号而且从该信号处理程序返回,则sigsuspend返回,在返回之前,将进程的信号屏蔽字设置为调用sigsuspend之前的值。
    注意,此函数没有成功返回值。如果它返回到调用者,则总是返回-1,并将 errno 设置为EINTR(表示一个被中断的系统调用)。
2.实例代码 1 (对原文代码稍有修改)
下面的程序显示了保护临界区,使其不被特定信号中断的方法。
               
               
               
                #include stdio.h>
#include stdlib.h>
#include signal.h>
#include errno.h>
static void sig_int(int);
static void sig_usr2(int);
void pr_mask(const char *str)
{
        sigset_t sigset;
        int errno_save;
        errno_save = errno; /* we can be called by signal handlers */
        if (sigprocmask(0, NULL, &sigset)  0)
                perror("sigprocmask error");
        printf("mask: %s", str);
        if (sigismember(&sigset, SIGINT)) printf("SIGINT ");
        if (sigismember(&sigset, SIGQUIT)) printf("SIGQUIT ");
        if (sigismember(&sigset, SIGUSR1)) printf("SIGUSR1 ");
        if (sigismember(&sigset, SIGUSR2)) printf("SIGUSR2 ");
        if (sigismember(&sigset, SIGALRM)) printf("SIGALRM ");
        /* remaining signals can go here */
        printf("n");
        errno = errno_save;
}
int main(void)
{
        sigset_t newmask, oldmask, waitmask;
        pr_mask("program start: ");
        if (signal(SIGINT, sig_int) == SIG_ERR)
                perror("signal(SIGINT) error");
        if (signal(SIGUSR2, sig_usr2) == SIG_ERR)
                perror("signal(SIGUSR2) error");
        sigemptyset(&waitmask);
        sigaddset(&waitmask, SIGUSR1);
        sigemptyset(&newmask);
        sigaddset(&newmask, SIGINT);
        sigaddset(&newmask, SIGUSR2);
        /*
         * Block SIGINT and save current signal mask.
         */
        if (sigprocmask(SIG_BLOCK, &newmask, &oldmask)  0)
                perror("SIG_BLOCK error");
        /*
         * Critical region of code.
         */
        pr_mask("in critical region: ");
        /*
         * Pause, allowing all signals except SIGUSR1.
         */
        if (sigsuspend(&waitmask) != -1)
                perror("sigsuspend error");
   
        pr_mask("after return from sigsuspend: ");
        /*
         * * Reset signal mask which unblocks SIGINT.
         * */
        if (sigprocmask(SIG_SETMASK, &oldmask, NULL)  0)
                perror("SIG_SETMASK error");
        /*
         * * And continue processing ...
         * */
        pr_mask("program exit: ");
        exit(0);
}
static void sig_int(int signo)
{
        printf("***************************************n");
        pr_mask("start sig_int: ");
        raise(SIGUSR2);
        pr_mask("exit sig_int: ");
        printf("***************************************n");
}
static void sig_usr2(int signo)
{
        pr_mask("in sig_usr2: ");
}
编译后运行,结果如下:
[liumin@localhost sigsuspend_1]$ ./m
mask: program start:
mask: in critical region: SIGINT SIGUSR2      //程序停在这里,然后键入中断字符
***************************************   
mask: start sig_int: SIGINT SIGUSR1
mask: in sig_usr2: SIGINT SIGUSR1 SIGUSR2
mask: exit sig_int: SIGINT SIGUSR1
***************************************
mask: after return from sigsuspend: SIGINT SIGUSR2  //从sigsuspend返回后,信号屏蔽字恢复为调用sigsuspend之前的值。
mask: program exit:
[liumin@localhost sigsuspend_1]$
实例代码 2:
使用 sigsuspend 函数,等待一个信号处理程序设置一个全局变量。下面的程序用于捕捉中断信号和退出信号,但是希望仅当捕捉到退出信号时,才唤醒主例程。
               
                #include stdio.h>
#include stdlib.h>
#include signal.h>
volatile sig_atomic_t quitflag; /* set nonzero by signal handler */
/* one signal handler for SIGINT and SIGQUIT */
static void sig_handler(int signo)
{
        if (signo == SIGINT)
                printf("ninterruptn");
        else if (signo == SIGQUIT)
                quitflag = 1; /* set flag for main loop */
}
int main(int argc, char *argv[])
{
        sigset_t newmask, oldmask, zeromask;
        if (signal(SIGINT, sig_handler) == SIG_ERR)
                perror("signal(SIGINT) error");
        if (signal(SIGQUIT, sig_handler) == SIG_ERR)
                perror("signal(SIGQUIT) error");
        sigemptyset(&newmask);
        sigemptyset(&zeromask);
        sigaddset(&newmask, SIGQUIT);
        /* Block SIGQUIT and save current signal mask */
        if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) != 0)
                perror("sigprocmask SIG_BLOCK error");
        while (quitflag == 0)
                sigsuspend(&zeromask);
        quitflag = 0;
        /* Reset signal mask which unblocks SIGQUIT */
        if (sigprocmask(SIG_SETMASK, &oldmask, NULL) != 0)
                perror("sigprocmask SIG_SETMASK error");
        exit(0);
}
编译运行结果:
               
                [liumin@localhost sigsuspend_2]$ ./m
                                               // Ctrl + C
interrupt
                                               // Ctrl + C
interrupt
                                               // Ctrl + C
interrupt                                      // Ctrl +  退出
[liumin@localhost sigsuspend_2]$
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/105349/showart_2132311.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP