同步和临界区:
实现可重入内核需要利用同步机制,因为如果当内核控制路径对某个内核数据结构进行操作时被挂机,那么,其它内核控制路径就不应当再对该数据结构进行操作。
对全局变量的安全访问通过原子操作来保证。
如果内核支持抢占,如Linux,那么在应用同步机制时,确保进入临界区前禁止抢占,退出临界区时启用抢占。
信号量:
可以把信号量看成一个对象,其组成如下:
- 一个整数变量
- 一个等待进程的链表
- 两个原子方法:down()和up()
每个要保护的数据结构都有它自己的信号量,其初始值为1。当内核控制路径希望访问这个数据结构时,它在相应的信号量上执行down()方法,若信号量的当前值不是负数,则允许访问这个数据结构,否则,把执行内核控制路径的进程加入到这个信号量的链表并阻塞该进程。当另一个进程在那个信号量上执行up()方法是,允许信号量链表上的一个进程继续执行。
自旋锁:
自旋锁与信号量非常相似,但没有进程链表;当一个进程发现锁被另一个进程锁着时,它就不停的“旋转”,执行一个紧凑的循环指令直到锁打开。
自旋锁在单处理器环境下是无效的。因为:当内核控制路径试图访问一个上锁的数据结构时,它开始无休止循环,则内核控制路径可能因为正在修改受保护的数据结构而没有机会继续执行,也没有机会释放这个自旋锁,最后的结果可能是系统挂起。
信号和进程间通信
Unix信号提供了系统事件报告给进程的一种机制
系统事件2种:
-
异步通告
-
同步错误或异常
POSIX标准定义了大约20种不同的信号,其中两种是用户定义的,可以当做用户态下进程通信和同步的原语机制。
对接收到的信号做出反应:
-
忽略该信号
-
异步地执行一个指定的过程(信号处理程序)
不指定方式,默认操作5种:
-
终止进程
-
将执行上下文和进程地址空间的内容写入一个文件,并终止进程
-
忽略信号
-
挂起进程
-
如果进程曾被暂停,则恢复它的执行
进程间通信机制:信号量、消息队列及共享内存,统称为IPC
进程管理
fork和_exit系统调用分别用来创建一个新进程和终止一个进程,而exec系统调用则是装入一个新程序,当前依赖硬件分页单元的内核采用写时复制技术,来实现fork