【问题标题】:When will the thread resume running after it has called sleep() or Sleep()?调用 sleep() 或 Sleep() 后,线程何时恢复运行?
【发布时间】:2020-08-31 18:23:12
【问题描述】:

根据 linux 程序员手册,其中说: “sleep() 使调用线程休眠,直到秒秒过去或没有被忽略的信号到达。”

我认为一个线程不会在睡眠时间到期后立即恢复执行。它可能醒得早或晚,还没有确定。对吧?

【问题讨论】:

  • 我认为它不会早起。它可能会晚一点醒来,具体取决于它计划再次运行的时间。
  • @Haris 我从 ubuntu 手册中找到了这个材料。 “sleep() 使调用线程休眠,直到秒秒过去或没有被忽略的信号到达。”所以,我认为它可能会被信号提前唤醒。
  • @sunshilong369 你是对的。 sleep() 调用可能会被信号中断。但这(以及您引用的文档)适用于 POSIX/Linux 系统。我不知道睡眠和信号在 Windows 上是如何工作的。此外,当然,您的线程可能会休眠更长时间,具体取决于它何时被安排执行,但它不应该有太大的区别。如果你想在有信号的情况下恢复睡眠,你可以使用nanosleep() - 同样,文档适用于 POSIX
  • 如果没有被信号“骚扰”,sleep 将保证其参数的最小数量(即,如果您指定 5,则等待将至少 5秒,并且由于调度延迟,一毫秒左右)。
  • @sunshilong369 由于调度策略和资源的可用性,任何等待/阻止等待某些资源的函数调用都可能需要无限的时间才能返回,如果这是您所要求的。您的程序不能强制内核在准确的时间(例如 3 秒)从睡眠状态恢复。但通常,您的执行将在 3 + 秒后恢复。

标签: c linux windows


【解决方案1】:

通常,线程不会提早唤醒(除非如上所述,有来自单独线程的信号向内核指示它应该这样做)。 在大多数内核中,睡眠函数的时间参数被解释为多个 SysTicks。然后,该任务向内核报告它认为至少不需要那么多滴答声的计算时间 - 因此它被排除在进程队列之外,直到 SysTick 寄存器大于(调用时的值)+(时间参数)。 通常,在没有陷入困境的抢占式内核中,睡眠调用将持续所需的时间 + 1 SysTick +- 1 SysTick(因此从准时到迟到的任何时间)。 也就是说,至少在嵌入式世界中。当您过渡到 x86 时,所有的时间都变得一团糟。

【讨论】:

  • 你所说的“通常情况下,在没有陷入困境的抢占式内核中,睡眠调用将持续所需的时间 + 1 SysTick +- 1 SysTick ”是什么意思(所以从准时到有点晚了)。" 有笔误(+ 1 SysTick +- 1 SysTick)吗?
  • 你所说的“当你过渡到 x86 时,所有的时间都变得一团糟”是什么意思。为什么?你能告诉我吗?
  • 按 1 SysTick +1 +/-1,我的意思是,根据我的经验,睡眠呼叫将至少持续所需的时间加上 0 到 2 个滴答声。请记住,在普通笔记本电脑上,滴答声大约每毫秒发生一次,因此以秒为单位测量延迟时,这种抖动可以忽略不计。
  • 是的,我明白了。谢谢你的分类。
  • 另外,x86 本质上并不是一个非决定性架构——它只是倾向于大多数为它编写的操作系统都不是“硬”实时的。例如,Linux 利用 niceness 来调度任务,通常将数十个线程设置为相同的优先级。另一方面,像 TI-RTOS 这样的硬实时内核明确地对线程进行优先级排序,每个优先级只有一个任务。如果两个不同重要性的线程准备好运行,“硬”实时操作系统可以保证较高优先级线程的延迟最小,而软实时内核可能不会。
【解决方案2】:

根据 linux 程序员手册,上面写着“此外,在睡眠完成后,在 CPU 再次空闲以再次执行调用线程之前可能仍有延迟。”。

所以时间未定。

【讨论】:

  • 是的,我同意你的看法。
猜你喜欢
  • 1970-01-01
  • 2011-05-06
  • 1970-01-01
  • 2013-10-13
  • 2012-12-14
  • 2015-11-16
  • 1970-01-01
  • 2019-02-18
  • 1970-01-01
相关资源
最近更新 更多