2017/04/29学习笔记

信号的概念

信号在我们的生活中随处可见,如:古代战争中摔杯为号;现在战争中的信号弹;体育比赛中使用的信号枪。。。
他们都有共性: 1.简单 2.不能携带大量的信息 3.满足某个特设条件才发送。
信号是信息的载体,Linux/Unix 环境下,古老 、经典的通信方式,现在依然是主要的通信手段.
Unix早期版本就提供了信号机制,但不可靠,信号可能丢失。Berkeley和AT&T都对信号模型做了修改,增加了可靠信号机制。但彼此不兼容。POSIX.1对可靠信号例程进行了标准化.

信号的机制

A给B发生信号,B收到信号之前执行自己的代码,收到信号后,不管执行到程序的什么位置,都有暂停运行,去处理信号,处理完毕再进行执行。与硬件中断类似--异步模式。但信号是软件层面上实现的中断,早期常被称“软中断”
信号的特质 由于信号是通过软件方法实现,其实现手段导致信号有很强的延时性。但对于用户来说这个延时非常短,不易察觉.
每个进程收到的所有信号,都是有内核负责发送的,内核处理.

与信号相关的事件和状态
产生信号
1.按键产生 如 Ctrl+c Ctrl+z Ctrl=\
2.系统调用 如 kill raise abort
3.软件条件产生 如 alarm
4.硬件异常 如:非法访问内存(段错误),除0,内存对齐出错
5.命令产生 如:kill命令
递达:递达并且到达进程

未决信号集

阻塞信号集(信号屏蔽字 set)

9号和19信号不允许忽略和捕捉,只能执行默认动作。

alarm函数

设置定时器,在指定seconds后,内核会给当前继承发送14信号。进程收到该信号,默认动作终止。
每个进程有且只有一个定时器 常用:取消定时器 alarm(0),返回旧闹钟剩余秒数。
定时与进程状态无关!就绪 运行 挂起 终止 僵尸 无论进程处于何种状态,alarm都计时

信号捕捉特性

进程正常运行时,默认PCB中有一个信号屏蔽字,他决定了进程自动屏蔽哪些信号。当注册了某个信号的捕捉函数,捕捉到该信号后,要调用该函数。而该函数有可能执行很长时间,在这期间所屏蔽的信号有sa_mask来指定。
XXX信号捕捉函数执行期间,XXX信号自动被屏蔽
阻塞的常规信号不支持排队,产生多次只记录一次。(后32个实时信号支持排队)

解决时序问题

可以通过设置屏蔽SIGGALRM的方法来控制程序执行逻辑,但无论如何设置,程序都有可能在“解除信号屏蔽”和“挂起等待信号”这两个操作间隙失去CPU。除非将这两个步骤合并成一个原子操作。sigsuspend函数具备这个功能。在对时序要求严格的场合下都应该使用sigsuspend替换pause.
sigsuspend函数调用期间,进程信号屏蔽字有其参数mask指定。
可以将每个信号从临时信号屏蔽字mask中删除,这样在调用sigsuspend时将解除对该信号的屏蔽,然后挂起,当sigsuspend返回时,进程的信号屏蔽字恢复原来的值。如果原来对该信号是屏蔽,sigsuspend函数返回后仍然屏蔽该信号

竞态条件,跟系统负载有很紧密的关系,体现出信号的不可靠。系统负载越严重,信号不可靠性越强。
不可靠由其实现原理所致。信号是通过软件方式实现,每次系统调用结束后或中断处理结束后,需要通过扫描PCB中的未决信号集,来判断是否应处理某个信号。当系统负载过重时,会出现时序混乱。
这种意外情况只能在编程中,提早预见,主动规避,而无法通过gdb程序调试等其他手段弥补。且由于其不具规律性,后期捕捉和重现十分困难。

时间: 2024-10-06 14:01:11

2017/04/29学习笔记的相关文章

2017/04/27学习笔记

fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数执行另一个程序.当进程调用一个exec函数时,该进程的用户空间和数据完全被新程序替换,从新程序的启动例程开始执行.调用exec并不创建新进程,所以调用exec前后该进程ID不变.将当前进程的.text .data替换为所要加载程序的.text .data,然后让进程从新的.text第一条指令开始执行,但进程ID不变,换核不换壳. int execl();int execlp();int

2017/04/20学习笔记

man man 查看帮助文档echo $PATHreboot 重启poweroff 关机 vim --vimvim是从vi发展过来的一款文本编辑器vim的三种工作模式命令模式--打开vim之后,默认模式编辑模式--需要输液一些命令,切换到编辑模式末行模式--在末行模式下可以输入一些命令 :号 aiosAIOS w保存光标移动HJKL行首:0行尾:$文件开始:gg结束:G行跳转: 300G x:删除光标所在字符u: 撤销X:删除光标前字符dw:删除单词d0:删除光标前d$:删除光标后 Ddd:删除

2017/04/05学习笔记

栈的应用 案例1:就近匹配几乎所有的编译器都具有检测括号是否匹配的能力如何实现编译器中的符号成对检测?#include <stdio.h> int main(){int a[4][4];int (*p)[4];p =a[0];return ;算法思路从第一个字符开始扫描当遇见普通字符时忽略当遇见左符号时压入栈中当遇见右符号时从栈中弹出栈顶符号,并进行匹配匹配成功:继续读入下一个字符匹配失败:立即停止,并报错结束:成功:所以字符扫描完毕,且栈为空失败:匹配失败或所有字符扫描完毕但栈非空当需要继承

2017/04/23学习笔记

#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <dirent.h> int getFileNum(char* root){ //open dir DIR* dir = NULL; dir = opendir(root); if(dir == NULL){ perror("opendir"); exit(1); } //遍历 struct dir

2017/04/22学习笔记

makefile中的函数 所以得makefile函数都是有返回值的 src=$(wildcard ./*.c) #从当前目录查找所有的.c文件obj=$(patsubst ./%.o, ./%.c, $(src)) #所有.c替换成点o .PHONY:clean 伪目标clean:rm $(obj) $(target) -f #删除.o和 目标 -f强制执行,不提示信息 clean:-rm $(obj) $target -f #命令前加 -,如果当前目录执行失败,忽略当前目录,继续向下执行 ma

2017.04 vue学习笔记---08表单控件绑定---基础用绑定value

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> <style> div{ margin-bottom: 30px; } </style> <script src="js/vue.js"></script> <

2017.04 vue学习笔记---08表单控件绑定---基础用法

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> <style> div{ margin-bottom: 30px; } </style> <script src="js/vue.js"></script> <

2017/05/05学习笔记

系统中所以的信息包括磁盘文件.内存中的程序.内存中存放的用户数据及网络上传送的数据都是由一串bit表示的.区分不同数据对象的唯一方法是我们读到这些数据对象时的上下文.为了在C程序中做出好的编码选择,我们确实需要了解一些机器代码以及编译器将不同的C语句转化为机器代码的方式.比如一个switch是否总是比一个if-else语句高效的多?一个函数调用的开销有多大?while循环比for循环更有效么?指针引用比数组索引更有效么为什么将循环求和的结果放到一个本地变量中,会比其放到一个通过引用传递过来的参数

Other - 04 - AspectJ学习笔记 - 切点表达式

SourceAnalysis - 50 - Spring - AspectJ 这篇的目的也比较直接,今天突然发现同事问到切点表达式发现自己还是不太熟悉 AspectJ 的切点表达式,只知道最简单的 execution 表达式,所以来整理一下一些切点表达式的使用方法,算是插入的一篇文章吧. 首先对于一个切点 pointcut 来说,它分为两个核心部分,第一部分是 joinpoint,第二部分是 pointcut.而切点本身的作用是选择需要被横切的逻辑块,而 before / after 等是 ad