内核竞态与抢占
最古老的操作系统是单进程的。后来出现了多任务操作系统,因为多进程在内核态中资源都是共享的,所以容易造成破坏,早期的进程调度器在内核态是不能被抢占的,在进入内核态的时候进程调度器停止调度,这样降低了内核的复杂程度。稳定性也相对较高,服务器中常用。更先进的内核,能够在内核态抢占,这就需要锁来保证内核线程间的同步
以下用两段代码说明
第一种 非竞态内核
static int test_init(void){ printk("test_init\n"); preempt_disable();for(;;); preempt_enable(); return 0;}module_init(test_init);
提示符下输入:
$insmod test.ko &
test_init
当模块加载时进入死循环,进入内核态时进程调度器停止工作,其他进程不会被调用到,所以机器就彻底死掉了
static int test_init(void){ printk("test_init\n"); //preempt_disable();for(;;); //preempt_enable(); return 0;}module_init(test_init);
提示符下输入:
$insmod test.ko &
test_init
$
$
当模块加载时进入死循环,但是进程调度器仍然在工作,所以后台进程依然可以继续工作
说明:
preempt_enable 允许抢占。
preempt_disable禁止抢占。
请参阅<深入理解linux内核>第5章
具体配置内核抢占方式
内核特性->
抢占模式->
三种抢占模式,内核态禁止抢占,自抢占内核,允许抢占内核