抢占关闭总结

本文是阅读宋宝华老师是谁关闭了Linux抢占,而抢占又关闭了谁?的这篇文章后的总结


1、抢占发生的必要条件

    a、preempt_count抢占计数必须为0,不为0说明其它地方调用了禁止抢占的函数,比如spin_lock

    b、中断必须是使能的状态,因为抢占动作要依赖中断

具体源码实现参考如下:


2、spin_lock系列函数总结

    a、spin_lock会调用preempt_disable函数关闭抢占

    b、spin_lock_irq会调用spin_lock函数和local_irq_disable函数(关闭中断)

    c、spin_lock_irqsave会调用spin_lock函数和local_irq_save函数(关闭中断,同时保存cpu对中断的屏蔽状态)

参考如下:


3、preempt_disable和local_irq_disable的区别

上面说过,两个函数都可以关闭抢占,他们的区别是什么?

他们的区别不在于关抢占和关中断函数,而是在对应的开抢占和开中断的地方,也就是preempt_enable()函数local_irq_enable()函数。


在preempt_enable函数中提供了一个抢占点,其它高优先级进程可直接抢占,代码如下


而local_irq_enable函数并没有提供抢占点,它的功能知识重新打开中断,高优先级的进程在这里无法立刻抢占,必须等该函数返回后的下一个抢占点才能抢占,下一个抢占点可能是:时钟tick处理返回、中断返回、软中断结束、yield()等等多种情况。

所以spin_unlock_irq函数先调用local_irq_enable,然后再调用preempt_enable函数,这样就可以让高优先级进程在spin_unlock_irq中进行抢占。


4、spin_lock系列函数关闭了抢占,但是并没有关闭调度

因为进程还可以主动sleep,但是这样做会存在很大的风险,是不推荐的,所以以下这种代码是不合理的,容易造成死锁


为了防止无意识的造成这种情况,可以打开内核中的DEBUG_ATOMIC_SLEEP选项,一旦发生则会报错


猜你喜欢

转载自blog.csdn.net/woyimibayi/article/details/80682084