time.sleep 与挂起(即待机和休眠)

2 投票
3 回答
2322 浏览
提问于 2025-04-15 15:57

比如说,如果我让程序暂停100秒(用time.sleep(100)),然后立刻把我的电脑休眠99秒,等我唤醒电脑后,接下来的代码会在1秒后执行,还是在100秒后执行呢?

如果答案是1秒,那我怎么才能让程序“睡”100秒,而不管休眠或待机的时间呢?

3 个回答

0

很明显,你的程序需要根据真实的时间来“睡觉”。

如果你让它根据其他某种时钟来“睡”,比如一个不太靠谱的时钟,那就会变得很麻烦。想想看,你的应用程序在“睡觉”,怎么能知道这个时钟什么时候开始和停止呢?对了,它必须被叫醒,告诉它因为系统在休眠,所以不应该运行。

或者,也许可以用一些超级复杂的操作系统调度程序来判断系统什么时候是“忙碌”的,什么时候是“休眠”的,这样就能决定这些时间是否算在各种正在“睡觉”的进程的时间表里。

这听起来太复杂了。

实际上,如果你仔细观察,程序的“睡眠”时间其实是相当不准确的,任何Unix信号都会打断它。所以有很多原因可能会让它提前醒来,最常见的就是按下Control-C。

3

我不太清楚你想要达到什么效果,不过

for i in range(100):sleep(1)

可能会有效,因为休眠的时间最多只会用到1秒钟。

5

time.sleep(N) 这个命令的意思是让程序暂停,至少暂停 N 秒,也就是“墙钟时间”。不过,不能保证这个暂停会正好是 N 秒;比如说,程序在 N 秒后准备好继续执行,但这时可能有其他程序正在运行,操作系统会决定哪个程序先执行,而不是编程语言来决定。此外,暂停也可能会因为各种事件(比如中断)而提前结束。

如果你能在你的操作系统中找到一种时钟工具,它只在你关心的系统状态下才会走,比如“没有进入休眠状态”,那么当然可以在“醒来”后再继续暂停。

举个例子,在 Windows 7 系统中,QueryUnbiasedInterruptTime 这个函数特别说明了“不会计算系统在休眠或休眠状态下的时间”,而且它的时间单位是 100 纳秒。所以如果你通过 ctypes 调用这个函数,就可以实现你想要的效果:

def unbiasedsleep(n):
  start = kernel32.QueryUnbiasedInterruptTime()
  target = start + n * 10 * 1000 * 1000
  while True:
    timeleft = target - kernel32.QueryUnbiasedInterruptTime()
    if timeleft > 0:
      time.sleep(timeleft / (10 * 1000 * 1000.0))

我不知道在其他版本的 Windows 或其他操作系统中如何获取类似于 QueryUnbiasedInterruptTime 的功能,不过你也没有告诉我们你感兴趣的是哪个操作系统,所以列出一大堆可能在不同环境中有效的方法其实也没什么意义。

撰写回答