- 调用cond_resched()时
- 显式调用schedule()时
- 从系统调用或者异常中断返回用户空间时
- 从中断上下文返回用户空间时
- 在系统调用或者异常中断上下文中调用preempt_enable()时(多次调用preempt_enable()时 , 系统只会在最后一次调用时会调度)
- 在中断上下文中 , 从中断处理函数返回到可抢占的上下文时(这里是中断下半部 , 中断上半部实际上会关中断 , 而新的中断只会被登记 , 由于上半部处理很快 , 上半部处理完成后才会执行新的中断信号 , 这样就形成了中断可重入)
而我们知道实时进程和普通进程是共存的 , 调度器是怎么协调它们之间的调度的呢 , 其实很简单 , 每次调度时 , 会先在实时进程运行队列中查看是否有可运行的实时进程 , 如果没有 , 再去普通进程运行队列找下一个可运行的普通进程 , 如果也没有 , 则调度器会使用idle进程进行运行 。
系统并不是每时每刻都允许调度的发生 , 当处于硬中断期间的时候 , 调度是被系统禁止的 , 之后硬中断过后才重新允许调度 。而对于异常 , 系统并不会禁止调度 , 也就是在异常上下文中 , 系统是有可能发生调度的 。
4.3 抢占标识TIF_NEED_RESCHED
内核在检查need_resched标识TIF_NEED_RESCHED的值判断是否需要抢占当前进程, 内核在thread_info的flag中设置了一个标识来标志进程是否需要重新调度, 即重新调度need_resched标识TIF_NEED_RESCHED, 内核在即将返回用户空间时会检查标识TIF_NEED_RESCHED标志进程是否需要重新调度
系统中每个进程都有一个特定于体系结构的struct thread_info结构, 用户层程序被调度的时候会检查struct thread_info中的need_resched标识TLF_NEED_RESCHED标识来检查自己是否需要被重新调度.
如果内核检查进程的抢占标识被设置, 则会在一个关键的时刻, 调用调度器来完成调度和抢占的工作
4.4 内核抢占和用户抢占
而根据进程抢占发生的时机, 抢占可以分为内核抢占和用户抢占, 内核抢占就是指一个在内核态运行的进程, 可能在执行内核函数期间被另一个进程取
一般来说 , 用户抢占发生几下情况:
- 从系统调用返回用户空间;
- 从中断(异常)处理程序返回用户空间
- 当从中断处理程序正在执行 , 且返回内核空间之前 。当一个中断处理例程退出 , 在返回到内核态时(kernel-space) 。这是隐式的调用schedule()函数 , 当前任务没有主动放弃CPU使用权 , 而是被剥夺了CPU使用权 。
- 当内核代码再一次具有可抢占性的时候 , 如解锁(spin_unlock_bh)及使能软中断(local_bh_enable)等, 此时当kernel code从不可抢占状态变为可抢占状态时(preemptible again) 。也就是preempt_count从正整数变为0时 。这也是隐式的调用schedule()函数
- 如果内核中的任务显式的调用schedule(), 任务主动放弃CPU使用权
- 如果内核中的任务阻塞(这同样也会导致调用schedule()), 导致需要调用schedule()函数 。任务主动放弃CPU使用权
struct thread_info
{
/* ...... */
int preempt_count; /* 0 => preemptable, <0 => BUG */
/* ...... */
}

文章插图
内核自然也提供了一些函数或者宏, 用来开启, 关闭以及检测抢占计数器preempt_coun的值, 这些通用的函数定义在include/asm-generic/preempt.h, 而某些架构也定义了自己的接口 , 比如x86架构/arch/x86/include/asm/preempt.h
推荐阅读
- 关于黄茶的采摘的介绍,黄茶的种类全介绍
- 君山银针可以冲泡几遍,如何冲泡好杯君山银针茶
- 君山银针品种大全,君山银针的特征
- js中同步和异步编程
- 温州黄汤冲泡步骤,温州平阳黄汤黄茶类中的黄小茶
- 君山银针哪个季节喝好,如何鉴别君山银针
- 黄芽茶适合女人喝吗,黄茶适合什么人喝
- 君山银针的贮藏方法,鉴别优质君山银针的方法
- 远安黄茶功效作用,黄茶知识
- 雅安黄茶简介,黄茶有哪些
