如果您查看所有BSD中可用的clock_gettime()函数并且实际上已定义为POSIX标准的一部分,您会看到至少支持三种类型的时钟(许多系统支持的时钟超过这些时钟) ,但实际上POSIX标准只要求一个存在,所有其他都是可选的):
CLOCK_REALTIME - POSIX要求它存在.这是挂钟时钟.
CLOCK_MONOTONIC - 不知道这是什么(和SI秒的意思),但我知道这个时钟永远不会跳回来,它只能单调增加价值.
CLOCK_UPTIME - 我看不出这与CLOCK_MONOTONIC有什么不同(正常运行时间也从不跳转),但至少我知道当内核启动时这个时钟从零开始(而没有定义内核启动时CLOCK_MONOTONIC的初始值) )
让我们暂时忽略其他时钟.CLOCK_REALTIME不保证单调向上计数,对吗?这是实际的"系统时间".我可以随意改变系统时间.我可以将它设置为过去3个月或未来5年,每次我的系统使用网络上的NTP服务器同步时间时,时间可能会向前或向后跳跃.
现在我们在BSD系统中有两个睡眠功能.sleep()和nanosleep().我不确定,但我希望sleep()能够在nanosleep之上实现,毕竟我可以通过使用nanosleep()轻松模拟sleep(),并且只设置struct timespec中的秒数,保持纳秒为零.
我已经从许多来源读到,这些功能实际上通过计算唤醒时间(获取当前时间,为其添加睡眠量)来工作,然后系统将定期检查当前时间是否晚于唤醒时间,如果是这样,它将再次唤醒线程.仅在间隔时间内检查的事实是手册页说明当前睡眠将至少睡眠这段时间(仅在被信号中断时更短)的原因,但它可能会睡得更久(取决于多久)系统检查我们是否已经超过唤醒时间,并取决于调度程序允许此线程再次运行所需的时间.
这对我来说完全是理智的......但有一个问题总是让我烦恼:
根据各种来源,睡眠(至少纳米睡眠)在内部使用CLOCK_REALTIME作为时钟.这意味着,如果告诉nanosleep()睡眠30秒,然后将系统时钟更改为1小时,线程将立即唤醒(未来1小时远远超过唤醒时间nanosleep( )计算).这也完全没问题.然而,如果我说在30秒内醒来然后用户发现他的系统时钟提前一小时并将他的时钟倒退一小时会发生什么?然后我的线程会睡1小时30秒?因为那会很糟糕.