sigsuspend 将重设signal mask和等待合成原子操作
来源:互联网 发布:免费网校系统php源码 编辑:程序博客网 时间:2024/06/10 11:58
先来看一段代码
sigset_t newmask, oldmask;
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 */
/* reset signal mask, which unblocks SIGINT */
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
err_sys("SIG_SETMASK error");
/* window is open */
pause(); /* wait for signal to occur */
/* continue processing */
这段代码中本来的意图是想要打开SIGINT,但是有可能在pause之前就收到了SIGINT信号,这样这个信号就丢失了。
所以提供了sigsuspend函数,使这两个操作成为一个原子操作。
下面的代码就是使用sigsuspend的例子。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>
static void sig_int(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("%s", str);
if (sigismember(&sigset, SIGINT)) printf("SIGINT ");
if (sigismember(&sigset, SIGQUIT)) printf("SIGQUIT ");
if (sigismember(&sigset, SIGUSR1)) printf("SIGUSR1 ");
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");
sigemptyset(&waitmask);
sigaddset(&waitmask, SIGUSR1);
sigemptyset(&newmask);
sigaddset(&newmask, SIGINT);
/*
* 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)
{
pr_mask("/nin sig_int: ");
}
运行结果是:
$./test
program start:
in critical region: SIGINT
in sig_int: SIGINT SIGUSR1 这一行出现两个信号的原因,是因为os会自动block正在接收的信号。
after return from sigsuspend: SIGINT
program exit:
- sigsuspend 将重设signal mask和等待合成原子操作
- 原子变量和原子操作
- 原子服务和合成服务的定义
- 条件变量 pthread_cond_wait 函数的解锁和等待为原子操作
- 设置 和 显示 当前进程的signal mask
- 关于使用sigsuspend(sigset_t* mask)阻塞进程
- volatile和原子操作
- 原子操作和信号量
- 原子操作和锁
- volatile和原子操作
- volatile和原子操作
- 原子操作和竞争
- 信号操作sigsuspend
- bitmaps位图和mask掩码常用操作
- 原子操作和内存屏障
- 多线程锁和原子操作
- 原子性操作和volatile
- 原子性操作和volatile
- servlet学习笔记(五)
- 在List当中删除重复数据.
- [转] RPM打包技术与典型SPEC文件分析
- 帮忙
- POJ 3264 Balanced Lineup(RMQ 线段树)
- sigsuspend 将重设signal mask和等待合成原子操作
- Oracle 10g客户端 安装(配图)
- 动态库的生成与对.so的读取(转)
- 字体安装
- 探讨Spring与Hibernate的整合所遇到的管理Session的问题
- 简述Session与Cookie区别
- js错误导致session丢失
- 手动创建oracle 10g数据库的命令语法
- Flex HTTPService 跨域访问