什么是同步问题,什么是临界区
实现可重入内核需要使用同步机制:保证了资源(一般是全局变量)的安全访问。例如多个进程同时操作同一个全局变量时,将有可能导致灾难性的后果,本文将介绍几种操作系统常用的方案来保证资源安全。
临界区:表示一段代码,进入这段代码的进程必须完成以后,另外一个进程才能进入。
同步机制解决方案:1.非抢占式内核、2、关中断、3、信号量、4、自旋锁。
1.非抢占式内核
当进程在内核态执行时,它不能被任意地挂起,也不能被另一个进程代替。因此在单处理器系统上,所有中断或异常处理程序不能更新的内核数据结构,内核对它们的访问都将是安全的。
缺点:在多处理器系统上是低效的,因为运行在不同CPU上的两个内核控制路径本可以并发地访问相同的数据结构。
2.关中断
在进入一个临界区之前禁止产生所有的硬件中断,离开临界区时再允许产生中断。这种同步机制操作简单。
缺点:当临界区比较大的时候,关中断会保持较长时间,这时候会导致硬件在较长时间里处于冻结状态。此外在多处理器系统上,这种机制不起作用,无法保证其他CPU不访问临界区中的同一数据结构。
3.信号量
该同步机制被广泛使用,在单处理器系统和多处理器系统上都有效。
信号量是与一个数据结构相关的计数器。当所有内核线程访问这个数据结构前,都要检查这个信号量。信号量的组成:一个整数变量、一个等待进程的链表、两个原子方法(加减信号量值)。信号量初始值为1,当进程需要访问被信号量访问的数据时,先减去一个信号量,如果不为负数,就允许访问,否则将该进程加入进程链表并阻塞它。一个进程访问完成之后对信号量加1,这时候允许进程链表中的一个进程执行。
4.自旋锁
尽管信号量已经非常完善,但是在一些情形下它不是解决问题的最佳方案,比如我们对需要被保护的资源操作的时间很短的时候,那么信号量就比较低效了,我们需要先检查信号量,在将进程插入到链表中,然后挂起它,这些操作都是比较费时的操作,当你完成这些操作时,可能另一个进程早就释放该信号量了。
这种时候多处理器系统就用到了自旋锁机制:当一个进程发现锁被另一个进程锁住时,它就不停地“旋转”,不断执行一个指令的循环直到锁打开。
缺点:在单处理器系统是无作用的,只在多处理器有用。单处理器中,会陷入无限循环,导致整个系统被挂起。
避免死锁
例子:进程p1获得访问数据结构a的权限,进程p2获得访问数据结构b的权限,但是p1在等待b,p2在等待a,这样就会导致这两个进程永远等不到,造成程序死锁,进程冻结。
所以在程序设计时,就要避免死锁风险,linux通过一下两种方式避免死锁,即引入很有限的信号量类型和以递增顺序请求信号量。
以上就是操作系统中对全局资源的保护机制啦,希望对你有所帮助,点个赞支持一下吧^_^