更改系统时间对睡眠线程有什么影响? [英] What is the effect of changing system time on sleeping threads?

查看:773
本文介绍了更改系统时间对睡眠线程有什么影响?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果您查看 clock_gettime()该功能在所有BSD中都可用,并且实际上已定义为POSIX标准的一部分,您会看到至少支持三种时钟类型(许多系统都支持这些时钟,但实际上POSIX标准只要求一种时钟即可).存在,其他所有都是可选的):

If you take a look at the clock_gettime() function, which is available in all BSDs and is actually defined as part of the POSIX standard, you see that there is support for at least three types of clocks (many systems support more than these clocks, but actually the POSIX standard only demands one to be present, all others are optional):

  • CLOCK_REALTIME -POSIX要求此功能存在.这是墙上的时钟.

  • CLOCK_REALTIME - POSIX demands this to be present. This is the wall time clock.

CLOCK_MONOTONIC -不知道这是什么(以及SI秒的含义),但我知道此时钟永远不会向后跳,只能单调增加值.

CLOCK_MONOTONIC - No idea what this is (and what SI seconds mean), but I understand that this clock will never jump backwards, it can only monotonically increase in value.

CLOCK_UPTIME -我看不到与CLOCK_MONOTONIC有何不同(正常运行时间也从不向后跳),但至少我知道内核启动时该时钟从零开始(而它尚未定义内核启动时CLOCK_MONOTONIC的初始值)

CLOCK_UPTIME - I fail to see how this is different to CLOCK_MONOTONIC (uptime also never jumps backwards), but at least I know that this clock starts at zero when the kernel boots (whereas it's not defined what initial value CLOCK_MONOTONIC will have when the kernel boots)

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

Let's ignore the other clocks for a second. CLOCK_REALTIME is not guaranteed to monotonically count upwards, right? This is the actual "system time". I can alter the system time at will. I can set it 3 month into the past or 5 years into the future and each time my system syncs time using a NTP server on the net, the time might jump forward or backward.

现在,在BSD系统中,我们有两个睡眠功能. sleep()

Now we have two sleeping functions in a BSD system. sleep() and nanosleep(). I'm not sure, but I would expect sleep() to be implemented on top of nanosleep, after all I can easily emulate sleep() by using nanosleep() and only set the number of seconds in the struct timespec, keeping nanoseconds zero.

我在许多资料中都读到,这些功能实际上是通过计算唤醒时间(获取当前时间,为其添加睡眠量)而起作用的,然后系统会定期检查当前时间是否为会比唤醒时间晚,如果是这样,它将再次唤醒线程.仅按间隔检查一次的事实是手册页说当前睡眠将至少睡眠此时间量的原因(仅在被信号中断的情况下才较短),但睡眠时间可能会更长(取决于频率)系统会检查我们是否已经超过唤醒时间,并取决于调度程序允许该线程再次运行所需的时间.

I have read at many sources, that these functions actually work by calculating the wake-up time (get current time, add sleep amount to it) and the system will then check in regular interval if the current time is later than the wake-up time and if so, it will wake up the thread again. The fact that this is only checked in intervals is the reason why the man pages say that the current sleep will sleep for at least this amount of time (shorter only if interrupted by a signal), but it may sleep longer (depending on how often the system checks if we are already past the wake-up time and depending on how long it takes before the scheduler allows this thread to run again).

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

This is all perfectly sane to me... but there is one question that always bugged me:

根据各种来源,睡眠(至少是nanosleep)在内部使用CLOCK_REALTIME作为时钟.这意味着,如果告诉nanosleep()睡眠30秒,然后将我的系统时钟更改为将来的1小时,则该线程将几乎立即唤醒(未来的1小时比nanosleep的唤醒时间还早)( )计算).这也完全可以. 但是,如果我说在30秒内醒来,然后用户发现自己的系统时钟提前了1个小时并将时钟向后设置了1个小时,会发生什么情况?然后我的线程将睡眠1小时30秒?那样会很糟糕.

According to various sources the sleeps (at least the nanosleep) use CLOCK_REALTIME as clock internally. This means, if tell nanosleep() to sleep for 30 seconds, then change my system clock to 1 hour in the future, the thread will wake up almost immediately (1 hour in the future is way ahead of the wake-up time nanosleep() calculated). This is also perfectly okay. However what happens if I say wake up in 30 seconds and then the user finds out that his system clock is one hour ahead and sets his clock backwards by one hour? Then my thread will sleep for 1 hour and 30 seconds? As that would be rather bad.

推荐答案

据我所知,睡眠函数通常更像是一个递减计数器.您说睡眠10秒钟",这在调度程序中转换为睡眠1000个计划滴答",然后,每次调度程序检查睡眠进程时,它都会减少剩余的时间.

As far as I know, sleep functions are usually implemented more like a decrementing counter. You say "sleep for 10 seconds," that translates into "sleep for 1000 schedule ticks" in the scheduler, and then every time the scheduler checks on sleeping processes it decrements the amount of time left.

通过这种方式,睡眠时间将始终是真实的睡眠时间,而不是直到将来某个时间才进入睡眠状态.原因是您所怀疑的,如果我们将来选择一个时间,我们可能永远都不会到达那里(或者可能会在意想不到的时间内到达那里).这与您希望在程序中使用sleep的方式是一致的.这并不是要进行类似日历的计算.

In this way, the sleep time will always be an amount of real time to sleep, as opposed to sleeping until some time in the future. The reason for this is as you've suspected, if we pick a time in the future we might never get there (or might get there in an unexpected amount of time). This is consistent with what you would want to use sleep for in a program. It's not meant to do calendar-like calculations.

您还可以进行简单的测试,使程序休眠30秒钟,使用nix"time"命令计时该功能的运行时间,然后在该功能启动后将系统时钟改回5分钟,然后看看会发生什么情况.

You can also make a simple test, make a program sleep for 30 seconds, use the nix "time" command to time how long the function runs, and after it starts change your system clock back 5 minutes and see what happens.

这篇关于更改系统时间对睡眠线程有什么影响?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆