我经常对 sleep()、阻塞调用、抢占概念感到困惑。据我了解,无论进程在做什么,抢占完全由调度程序完成。除非进程处于某个临界区或执行原子指令,否则调度程序可以根据调度算法抢占该进程并将其放入等待进程列表中。
另一方面 sleep() 调用调度程序在指定的时间间隔内阻止它;作为参数传递给 sleep()。
阻塞调用就像等待操作完成,如磁盘读/写、来自另一个设备的信号等 I/O 操作。
有人可以以更全面的方式向我解释这些工作的原理,或者向我指出一些可靠的资源吗?谢谢。
我经常对 sleep()、阻塞调用、抢占概念感到困惑。据我了解,无论进程在做什么,抢占完全由调度程序完成。除非进程处于某个临界区或执行原子指令,否则调度程序可以根据调度算法抢占该进程并将其放入等待进程列表中。
另一方面 sleep() 调用调度程序在指定的时间间隔内阻止它;作为参数传递给 sleep()。
阻塞调用就像等待操作完成,如磁盘读/写、来自另一个设备的信号等 I/O 操作。
有人可以以更全面的方式向我解释这些工作的原理,或者向我指出一些可靠的资源吗?谢谢。
当进程执行阻塞调用时,它会等待操作完成。
我不完全确定您是否正确理解了这一点。假设您的程序发出一个 I/O 命令,例如read()
. 您的进程不会等待操作完成:在 I/O 操作完成之前它不会占用处理器。当read()
被调用时,处理器的控制权交给操作系统,操作系统会提示 I/O 操作。与 CPU 速度相比,这些操作非常慢,并且它们由专用硬件执行,这意味着 CPU 在此期间可以自由执行其他操作,直到硬件发出信号通知它已完成(通过硬件中断,例如实例)。
从运行的程序来看read()
,它只知道read()
被调用了:指向当前指令的寄存器没有改变,它的虚拟内存和以前一样。该过程被“阻止”。这并不意味着 CPU 没有运行。
从操作系统的角度来看,程序处于等待模式,直到硬件发出信号它已经执行了它的任务。与此同时,调度器唤醒了另一个进程,恢复了它的上下文(即,CPU 寄存器的值已经设置为它们刚刚睡着之前的值,等等),并开始执行它的代码。
硬件完成后,会发生中断,操作系统通过将进程标记为可执行来确认它。根据调度程序策略,它可以恢复进程上下文并立即开始执行它,或者等到当前进程完成其时间片后再切换上下文。
阅读更多关于 linux 调度器的实现:Understanding the linux kernel 是一本非常好的书。
你的观点是绝对正确的。http://en.wikipedia.org/wiki/Preemption_(computing) (链接)