posix - 改变系统时间对休眠线程有什么影响?

标签 posix sleep bsd clock

如果你看看 clock_gettime()函数,它在所有 BSD 中都可用并且实际上被定义为 POSIX 标准的一部分,你会看到至少支持三种类型的时钟(许多系统支持的时钟不止这些,但实际上 POSIX 标准只需要一种到出席,所有其他人都是可选的):

  • CLOCK_REALTIME - POSIX 要求存在这一点。这是挂钟。
  • CLOCK_MONOTONIC - 不知道这是什么(以及 SI 秒是什么意思),但我知道这个时钟永远不会向后跳,它只能单调增加值。
  • CLOCK_UPTIME - 我看不出这与 CLOCK_MONOTONIC 有何不同(正常运行时间也永远不会向后跳),但至少我知道这个时钟在内核启动时从零开始(而它没有定义内核启动时 CLOCK_MONOTONIC 将具有的初始值)

  • 让我们暂时忽略其他时钟。 CLOCK_REALTIME 不能保证单调向上计数,对吗?这是实际的“系统时间”。我可以随意更改系统时间。我可以将它设置为过去 3 个月或 future 5 年,每次我的系统使用网络上的 NTP 服务器同步时间时,时间可能会向前或向后跳跃。

    现在我们在 BSD 系统中有两个 sleep 函数。 sleep()nanosleep() .我不确定,但我希望 sleep() 能够在 nanosleep 之上实现,毕竟我可以通过使用 nanosleep() 轻松模拟 sleep() 并且只在结构 timespec 中设置秒数,保持纳秒为零.

    我已经阅读了很多来源,这些函数实际上是通过计算唤醒时间(获取当前时间,添加 sleep 量)来工作的,如果当前时间晚于唤醒时间,系统将定期检查时间,如果是这样,它将再次唤醒线程。这只是在间隔中检查的事实是手册页说当前 sleep 将至少 sleep 这段时间的原因(只有在被信号中断时才更短),但它可能 sleep 更长时间(取决于多长时间)系统检查我们是否已经过了唤醒时间,并取决于调度程序允许该线程再次运行之前需要多长时间)。

    这对我来说完全是理智的……但有一个问题一直困扰着我:

    根据各种来源, sleep (至少是 nanosleep)在内部使用 CLOCK_REALTIME 作为时钟。这意味着,如果告诉 nanosleep() 休眠 30 秒,然后将我的系统时钟更改为 future 1 小时,线程将几乎立即唤醒( future 1 小时比唤醒时间 nanosleep( ) 计算)。这也完全没问题。 然而如果我说 30 秒后唤醒,然后用户发现他的系统时钟提前一小时并将他的时钟向后设置一小时,会发生什么?那么我的线程会休眠 1 小时 30 秒吗?因为那会很糟糕。

    最佳答案

    据我所知, sleep 功能通常更像是一个递减计数器。您说“ sleep 10 秒”,在调度程序中翻译为“ sleep 1000 个调度滴答”,然后每次调度程序检查 sleep 进程时,它都会减少剩余的时间。

    通过这种方式, sleep 时间将始终是实际 sleep 时间,而不是直到 future 某个时间才 sleep 。原因正如您所怀疑的那样,如果我们选择 future 的某个时间,我们可能永远不会到达那里(或者可能会在意想不到的时间内到达那里)。这与您希望在程序中使用 sleep 的目的一致。它并不意味着进行类似日历的计算。

    你也可以做一个简单的测试,让程序休眠 30 秒,使用 nix "time"命令来计算函数运行的时间,在它启动后将你的系统时钟调回 5 分钟,看看会发生什么。

    关于posix - 改变系统时间对休眠线程有什么影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/427808/

    相关文章:

    md5 - BSD md5 与 GNU md5sum 输出格式?

    linux - 理解 Linux 中的 read()

    c - 非阻塞标准输出[C/Linux]

    iphone - 让 AVFoundation 框架在屏幕褪色时不褪色

    linux - Bash:无限 sleep (无限阻塞)

    java - 让循环等待 5 分钟再执行

    c - 当我阅读 bsd 4.4 的核心代码时,无法处理似乎不必要的指针

    c - 多线程素数生成器

    shell - 如何对可移植 POSIX shell 脚本进行语法检查?

    macos - OS X上的grep -f产生段错误