linux信号done
linux信号done
- 1 内核态深入理解
- 2 重谈信号捕捉
- 3 信号捕捉的操作
- 3.1 sigaction
- 4 可重入函数
- 5 volatile
- 6 SIGCHLD(选学了解)
1 内核态深入理解
(1)上一章我们已经了解了当我们开启电脑时,OS是首先被加载到内存中的软件,这里我们谈论的内存为4GB,其中1GB左右为内核区,3GB为用户区,用户区有用户级页表,内核区有内核级页表,对于内核区我们一般只关心系统调用。
(2)我们关心系统调用的地址吗?
---- 不关心,我们只关心系统调用号,我们调用任何函数(库,系统调用)都是在自己的进程地址空间中调用的,因为内核级页表有且只有一份,所以无论OS如何切换进程,都能找到一个OS
(3)虽然我们在用户区可以随意访问自己的代码和数据,但是当我们想要访问内核区时,必须由用户态切换为内核态(因为无论在哪个进程中OS的代码和数据在内核区(3–4GB区),如果我们直接使用汇编修改寄存器内的值那么不就可以直接访问OS吗?所以OS做了一定的预防)
(4)不管是通过哪一个进程的地址空间进入内核,都是通过软中断进入操作的!
(5)其实我们处理哪一个状态不是由处在内核页表、内核代码还是用户代码来决定的,本质上是由CPU来决定的,CPU中有一个寄存器(C-S段寄存器),其中由一个代码段地址,它有一个标识位(取值叫做CPL),0(内核),3(用户态),linux只用0,3这两个数字,其他OS不一定
用户如何进入内核态?
1、时钟/外设中断
2、异常
3、陷阱(int 0x80)
(7)结论
2 重谈信号捕捉
(1)信号捕捉方法执行的时候,为什么要做权限切换(内核和用户),直接内核做不就行了吗?
---- 这里的handler如果是默认和忽略还好,但是handler可以由用户自定义,万一用户在代码里有一些损害OS的行为,OS就会被破坏,有安全风险
(2)信号处理完只能从内核返回(一个函数要想运行完回到另一个函数,必须要有调用关系)
3 信号捕捉的操作
3.1 sigaction
demo:
1、在处理信号期间有没有可能陷入内核?如果在陷入期间再来一个该信号,是不是会导致该方法不断递归,这样就会栈溢出(OS不允许信号处理方法嵌套,当某一个信号正在被处理,OS会自动把对应信号的block位置1,信号处理完成自动解除)
2、sa_mask:自定义屏蔽信号
3、pending位图是在执行信号处理方法之前清0,还是在执行完之后清0?
---- 执行之前清0,因为如果执行完之后清0的话,我们分不清该信号是执行该处理方法之前的,还是该信号在处理中又发送的
4 可重入函数
1、一个函数,被两个以上的执行流同时进入(重入)
2、若是由于重入出问题那么该函数是不可重入函数,否则为可重入函数
如果⼀个函数符合以下条件之⼀则是不可重⼊的:
• 调⽤了malloc或free,因为malloc也是⽤全局链表来管理堆的。
• 调⽤了标准I/O库函数。标准I/O库的很多实现都以不可重⼊的⽅式使⽤全局数据结构。