许多操作系统参考都说,在协作式(而不是抢占式)多任务处理中,进程将保持CPU直到它明确地自愿挂起自身。如果正在运行的进程执行了无法立即满足的I / O请求(例如,请求尚不可用的击键),那么调度程序是否将其挂起,或者它确实保留了CPU,直到可以为该请求提供服务为止?
[进行了编辑,以“执行无法立即满足的I / O请求”替换“ I / O上的块”。]
许多操作系统参考都说,在协作式(而不是抢占式)多任务处理中,进程将保持CPU直到它明确地自愿挂起自身。如果正在运行的进程执行了无法立即满足的I / O请求(例如,请求尚不可用的击键),那么调度程序是否将其挂起,或者它确实保留了CPU,直到可以为该请求提供服务为止?
[进行了编辑,以“执行无法立即满足的I / O请求”替换“ I / O上的块”。]
Answers:
在真正的“合作”设置中,如果没有硬件保护,则进程肯定会阻塞I / O,并且在完成I / O之前不会放弃控制(或者根本不会放弃控制)。例如,Windows 3.1就是这样:如果单个用户进程想要接管整个计算机,并阻止其他任何程序运行,则可以。
但是,在具有多任务的系统上,您希望系统API I / O命令在调用时会放弃对处理器的控制。因此,当正在运行的进程在I / O上阻塞时,假设该进程使用正常的系统API,则其他进程将被允许运行,直到I / O完成,并且最终的原始进程将在I / O完成后恢复。 。换句话说,调用阻塞I / O函数是协作系统上的进程可以自动挂起自身的一种方式。
如果正在运行的进程在I / O上阻塞
阻止IO几乎等同于暂停进程。在linux内核的上下文中,执行诸如的IO系统调用read()
将导致sysenter
或中断处理程序触发来照顾该IO,do_sys_read()
最终进行调用。在此,如果当前请求不能立即得到满足,则该函数调用sched()
然后可以执行另一个过程。
在协作系统的上下文中,我希望当您出于某些IO原因进行系统调用时,如果无法满足该请求,则内核将选择另一个任务并执行该任务。本文档提供了一些背景知识-基本上,如果您等待IO,则可能会永远挂在上面等待该IO。协作调度的想法是sched()
,如果执行CPU密集型任务,则经常调用或等效的cpu方法。
内核模式的考虑变得更加有趣。在某些可用的体系结构(例如某些嵌入式平台)上,仍然会调用中断处理程序来响应硬件或软件中断。在实现方面,通常有可能禁用 中断处理,但这也有缺点。
在协作调度(最好是cooperative multitasking
)模型中,从操作系统对进程运行多长时间没有任何控制的意义上讲,没有调度程序的概念。
正确编程的应用程序将自愿放弃I / O上的CPU。但是,写得不好的应用程序可能只会继续等待I / O,从而阻塞其他进程。
PS:后来,大多数操作系统都放弃了这种方法,转而采用抢先式调度(具有外部调度程序),现在,我们有各种操作系统使用的各种调度算法。
编辑:我的答案是基于其原始形式(几年前:P)中描述的日程安排。正如Gilles所说,某些系统仍在使用协作调度。并且有一个调度程序。我不确定这些系统是否以原始形式使用COS。