2009-11-12 28 views
17

我只关心如何sleep(time in ms)在C库或基本上在操作系统级别实现...在OS级别如何实现睡眠?

我猜...

  1. 可能是基于你做的处理器速度虽然nop的循环(我不确定睡眠时间是否准确)...
  2. 处理器中的任何特殊寄存器,您在其中写入某个值并且处理器仅停止指定的时间(这会非常低效,因为处理器甚至不能运行其他程序)。

任何线索?可能C库的源代码可以解释一下吗?我并不太在乎“C”是如何实现它的......我只是想知道“睡眠()”函数是如何实现的。

回答

14

Sleep()在OS级别实现。当任务/线程/进程正在休眠时,处理器不会旋转。这个特定的线程被放到待处理的队列中(线程还没有准备好运行),直到时间到了,线程将被放置在准备运行的队列中。

与此同时,准备运行的其他线程将运行。

只有直到发生硬件中断时没有线程准备运行将操作系统进入空闲线程,这在一般发出关机指令(或进入低功耗状态反正)处理器。

仅适用于非常简单的系统(如最简单的嵌入式系统),实际上可能只是实现为一个繁忙的等待循环。

任何操作系统教科书(如"Modern Operating Systems" by Tanenbaum)都会对此进行详细介绍 - 几乎所有操作系统(即使是旧的,便宜的)。

+0

ahhh ..所以它不保证在超时后唤醒..它的调度器或基本上在系统中的其他任务......? – FatDaemon 2009-11-12 00:43:13

+3

超时过期后,任务将再次运行取决于调度程序。系统可以保证它会在超时过期后立即运行,但是我认为大多数情况下只会将它放在准备运行的队列中的适当位置(如果线程优先级大于任何其他),它会在下一次计划时运行。 – 2009-11-12 00:46:07

+0

许多嵌入式处理器都有专用的睡眠指令 – mocj 2009-11-12 02:20:27

2

您的问题的答案完全取决于操作系统和实施。

一个简单的方法来想一想:当你调用sleep(),操作系统计算唤醒时间,然后坚持你的优先级队列过程中的某个地方。然后,它不会安排您的进程获取任何执行时间,直到足够的时间才能从队列中弹出来的真实

1

你不做任何while循环,否则系统将无法做任何事 - 而不是鼠标,键盘,网络响应等

通常是大多数操作系统做的是你加延迟到当前时间戳以获取请求延迟的任务时的时间戳(假设此时没有运行更高优先级的任务)并将[wakeupTimestamp,任务指针]添加到按升序排序的列表按时间戳。之后,操作系统执行上下文切换并运行下一个可用任务。系统会定期将困倦列表上的最早时间戳与当前时间戳进行比较,如果截止日期已过,则会将睡眠任务移至“就绪”任务队列中。

+0

你怎么在第二部分中说出一些聪明的东西,而在第一部分中又如此愚蠢?一个while循环是可抢占的,不会中断任何鼠标事件。 – 2013-03-26 02:54:04

2

在一个典型的操作系统,睡眠调用到内核,它设置进程等到指定的时间已经过去,然后去,发现一些其他进程运行。如果没有更好的做法,它将运行'闲置过程'。一旦时间流逝,调度程序将会注意到睡眠过程很顺利,并且会再次调度。

+0

绝对需要注意的是,空闲进程是运行HLT指令的进程。在现代CPU中,它变得非常复杂,并且取决于睡眠时间段,它会下降到CN模式。 (C0清醒,C1短暂睡眠,... C7长时间睡眠) – 2013-03-26 02:51:58

1

睡眠会阻止您传递时间值的任务/线程。您的任务在那段时间内无法运行,或者直到发生其他有趣的事情(如信号),无论哪个更早。

睡眠呼叫select()并不常见,并且不传递描述符以等待并且超时值等于您的睡眠周期。

系统可以通过设置一个计时器在时间过去后到期,然后等待该计时器到期时将用信号发送的信号来实现此目的。因此它在信号量上被阻塞。