APUE读书笔记:关于sigsuspend
sigsuspend是一个原子操作,为了防止信号丢失而存在的,具体含义看下函数原型。
int sigsuspend(const sigset_t *mask);
先忽略参数,sigsuspend完成的操作是阻塞进程的运行,直到有信号的产生。这样来看与另一个函数的作用相同。pause()
加上参数来理解,sigsuspend完成的操作是阻塞进程的运行,如果信号是mask参数设置的信号集,那么该信号是pending状态,而不会影响进程的阻塞状态,意思是进程仍然在阻塞中,直到不在信号集中的信号出现,进程能够继续执行。注意:如果之前确实有在mask信号集中的信号出现,该信号会在sigsuspend函数返回后被进程所捕获,完成自定义的或者默认的信号响应函数。
实验:sigsuspend对SIGINT信号设置屏蔽,在阻塞期间先发送SIGINT信号,再发送SIGUSR1信号
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h> static int proc_sig=;
sigset_t zeromask; void pr_mask(const char* str); void proc_usr1(int)
{
printf("proc_usr1\n");
pr_mask("In sigusr1:");
}; int main()
{
sigset_t sigset, oldmask, waitmask; signal(SIGUSR1, proc_usr1); sigprocmask(, NULL, &oldmask); //sigaddset(&sigset, SIGUSR1);
//sigprocmask(SIG_BLOCK, &sigset, NULL);
//pr_mask("Block SIGUSR1"); pr_mask("Before suspend"); sigaddset(&waitmask, SIGINT);
sigsuspend(&waitmask); pr_mask("After suspend:"); //sleep(12);
//sigprocmask(SIG_UNBLOCK, &sigset, NULL);
//pr_mask("Unblock SIGUSR1"); sleep(); return ;
} void pr_mask(const char * str)
{
sigset_t sigset;
sigprocmask(, NULL, &sigset); printf("%s:", str); if (sigismember(&sigset, SIGCHLD)) printf("SIGCHLD ");
if (sigismember(&sigset, SIGALRM)) printf("SIGALRM ");
if (sigismember(&sigset, SIGUSR2)) printf("SIGUSR2 ");
if (sigismember(&sigset, SIGUSR1)) printf("SIGUSR1 ");
if (sigismember(&sigset, SIGSTOP)) printf("SIGSTOP ");
if (sigismember(&sigset, SIGKILL)) printf("SIGKILL ");
if (sigismember(&sigset, SIGINT)) printf("SIGINT "); printf("\n");
}
运行:先ctrl+C(发送SIGINT信号),后发送信号SIGUSR1(kill -SIGUSR1 pid)
输出:
Before suspend:
^Cproc_usr1
In sigusr1::SIGUSR1 SIGINT
输出解释:第一行输出表示该进程未设置信号屏蔽字
第二行看到Ctrl+c的信号,之后的是信号响应函数proc_usr1的输出
第三行也是proc_usr1的输出当前进程的屏蔽字有SIGINT(由sigsuspend设置),还有SIGUSR1(不懂为啥SIGUSR1也会出现在当前屏蔽字中)
对于上面的问题:为啥SIGUSR1也会出现在当前屏蔽字中?
假设当前进程接受到了SIGUSR1信号,进入proc_usr1的信号处理函数,在函数执行期间,又收到了一个SIGUSR1信号,进程会怎么处理呢?
os应该先接受该信号,在SIGUSR1的响应函数结束后,os把该信号扔到当前进程,当前进程继续响应该SIGUSR1。
这样就能够解释了为啥SIGUSR1信号被屏蔽了,再某个信号的响应函数内,该信号一定会被设置为阻塞的,即响应函数处理时间内当前进程不要响应该信号。
APUE读书笔记:关于sigsuspend的更多相关文章
- APUE读书笔记:进程控制
重点函数:fork,exit,_exit 一.fork 函数原型: #include <unistd.> pid_t fork(void) 函数说明:fork函数将创建一个子进程,该函数调 ...
- APUE读书笔记-第17章-高级进程间通信
17.1 引言 *两种高级IPC:基于STREAMS的管道(STREAMS-based pipe)以及UNIX域套接字(UNIX domain socket)可以在进程间传送打开文件描述符.服务进程可 ...
- APUE 读书笔记 -----孤儿进程与僵尸进程[总结] +数据结构+C
http://www.cnblogs.com/Anker/p/3271773.html
- APUE读书笔记-第18章-终端I/O
18.1 引言 *终端I/O的用途很广泛,包括用于终端.计算机之间的直接连线.调制解调器以及打印机等等,所以终端I/O系统非常复杂 18.2 综述 *终端I/O有两种不同的工作模式: (1)规范模式输 ...
- APUE读书笔记-第14章-高级I/O
14.1 引言 *高级I/O包括非阻塞I/O.记录锁.系统V流机制.I/O多路转换(select和poll函数).readv和writev函数以及存储映射I/O(mmap) 14.2 非阻塞I/O * ...
- APUE读书笔记-第13章-守护进程
第13章 守护进程 13.1 引言 *守护进程也称精灵进程(daemon)是生存期较长的一种进程.它们常常在系统自举时启动,仅在系统关闭时才终止.因为它们没有控制终端,所以说它们是在后台运行的.UNI ...
- APUE读书笔记-第15章-进程间通信
15.1 引言 *进程之间交换信息的方法可以经由fork或exec传送打开文件,或者通过文件系统 *进程之间相互通信的其他技术——IPC(InterProcess Communication)包括半双 ...
- Node.js高级编程读书笔记Outline
Motivation 世俗一把,看看前端的JavaScript究竟能做什么. 顺便检验一下自己的学习能力. Audience 想看偏后台的Java程序员关于前端JavaScript的认识的职业前端工程 ...
- 读书笔记汇总 - SQL必知必会(第4版)
本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...
随机推荐
- Linq入门
一.Linq需要的C#语法支持: 1.隐式变量的使用var var使用时必须初始化 var是强类型数据 2.自动属性:public string FirstName{get ;set;} 3 ...
- JavaScript动态加载资源【js|css】示例代码
在开发过程中会用到各种第三方的插件,或者自己写在单独文件中的js方法库或者css样式,在html头部总是需要写一大堆的script和link标签,如果想要自己实现动态的引入资源文件,可以使用开源的re ...
- php中的curl常用例子
1.基本请求 <?php $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "http://www.baidu.com"); ...
- ping 计算机全名,返回的不是IP地址
今天想看一下机子的IP地址,结果关闭局域防火墙后,在命令行中使用ping 计算机全名,返回的不是IP地址 其实,这也是一种IP地址,IP6地址 原因:默认情况下,win7以上的操作系统,ping 计算 ...
- Ray Tracing
Ray Tracing 题目链接:http://codeforces.com/problemset/problem/724/C 拓展欧几里得 //为什么这次C题这么难啊=.= 可以观察到,光线在矩形中 ...
- Inverse属性和cascade属性以及集合的多对多关系
Inverse属性 Inverse属性,是在维护关联关系的时候起作用的. 表示控制权是否转移.(在一的一方起作用) Inverse = true, 控制反转. Inverse = false 不反转 ...
- 第五十九节,模拟浏览器请求Python结合html基本格式
模拟浏览器请求Python结合html基本格式 用Python模拟一个客户端,结合打开一个HTML页面 创建客户端 #!/usr/bin/env python # -*- coding:utf8 -* ...
- Eclipse版本区别
各版本的区别: Eclipse IDE for Java Developers 是Eclipse的platform加上JDT插件,用来java开发的 Eclipse IDE for Java EE D ...
- ssh原理[转]
SSH是每一台Linux电脑的标准配置. 随着Linux设备从电脑逐渐扩展到手机.外设和家用电器,SSH的使用范围也越来越广.不仅程序员离不开它,很多普通用户也每天使用. SSH具备多种功能,可以用于 ...
- 10.按要求编写Java应用程序。 (1)创建一个叫做People的类: 属性:姓名、年龄、性别、身高 行为:说话、计算加法、改名 编写能为所有属性赋值的构造方法; (2)创建主类: 创建一个对象:名叫“张三”,性别“男”,年龄18岁,身高1.80; 让该对象调用成员方法: 说出“你好!” 计算23+45的值 将名字改为“李四”
package com.hanqi.test; public class People { private String name,sex; private int age; private doub ...