Python time.sleep() 中的上限是多少?

9

你可以使用time.sleep()函数来让线程休眠,但是是否有休眠时间的上限呢?我在使用该函数时遇到了问题,当休眠时间较长(比如超过1k秒)时,无论是在Windows还是Unix平台上都会出现问题。


4
是的,有一个上限:当有人绊倒了你机器的电源线时;-) - Boldewyn
4
你遇到了什么“问题”?请具体说明。 - Jonathan Feinberg
我的猜测是这是特定于平台的,但我没有足够的知识来证明任何事情。 - Boldewyn
7个回答

12

其他人已经解释了为什么你可能睡眠时间少于你要求的时间,但是没有告诉你如何应对这种情况。如果你需要确保至少睡眠 n 秒,你可以使用以下代码:

from time import time, sleep
def trusty_sleep(n):
    start = time()
    while (time() - start < n):
        sleep(n - (time() - start))

这可能会睡眠超过n秒,但在至少睡眠n秒后才会返回。


1
不要犯和 @mykhal 一样的错误,睡眠时间分散累积会导致总睡眠时间明显超过预期。 - Peter Hansen

8

我认为时间越长,文档中描述的情况就越有可能发生:

实际挂起时间可能会比请求的时间少,因为任何捕获的信号都将终止sleep()在执行该信号的捕获例程后。此外,由于系统中其他活动的调度,挂起时间可能比请求的时间长任意数量。


复制粘贴的奇妙之处...(请参见eliben的答案)。然而,附带链接的+1。 - Boldewyn
@Boldewyn:只是因为我的火狐浏览器卡住了,所以我比Eli晚了3秒钟。 - SilentGhost
@Boldewyn:我们确实提供不同的评估。 - SilentGhost
除了可能的等待时间之外,似乎还存在一个硬限制,在不同版本中有所不同。 - okie

7

6

对于我的计算机而言,实际答案是:4294967.2950000003911900999秒。

注:该时间已按照ISO 8601格式进行表示。
sleep(4294967.2950000003911901)

OverflowError: 睡眠时间过长


11
你是怎么得到那个数字的? - SherylHohman
你是一个神秘的先生。 - Rohit Rawat
@Matt 有趣! - Ann Zen
1
在Windows 10上,阈值对我来说看起来是一样的。 - Gqqnbig
有趣的是,我在Repl.it Python编译器上使用我的iPad进行测试,但似乎它有比这更大的限制。 - okie
在PyCharm上测试,4294968确实。 - okie

1

通过在循环中加入短延迟的睡眠,您可以避免可能出现的问题:

def sleep(n):
    for i in xrange(n):
        time.sleep(1)

1
这个有所改善,但如果sleep()调用被提前中断,它仍然可能睡眠时间少于n。 - samtregar
1
好的,在这种情况下,我会更改函数为:t0 = time.time(); while time.time() < t0 + n: sleep(1) - mykhal

1

抱歉,在发布之前没有看到其他答案。 - zpon

0

我也遇到了一个情况,需要问自己这个问题。在我的情况下,我的线程需要长时间休眠(几天、几个月)。正如matt回答的那样,有一个限制。在他和我的系统中,限制是4.29百万秒+,不同的系统有不同的限制,正如mats回答评论中的某人所说,Repl.it有更大的限制。

总之,我们受到了限制,但我找到了一个解决方法,就是将秒数分成块,使用max_sleep_secs循环遍历这些块并进行休眠。

import time


def sweet_dreams(secs: float):
    DEBUG = False
    max_sleep_secs = 1000000
    secs_extra_ms = 0

    if secs > max_sleep_secs:
        if type(secs) is float:
            secs_extra_ms = str(secs).split('.')[-1]
            if secs_extra_ms:
                secs_extra_ms = secs_extra_ms.lstrip('0')

            secs_extra_ms = float(f"0.{secs_extra_ms}")

        secs = int(secs)
        secs_divide = float(secs) / max_sleep_secs  # e.g: 2.4123
        secs_int = int(secs_divide)  # e.g: 2
        secs_decimal_remainder = int(str(secs_divide).split(".")[-1])  # e.g 4123
        chunks = [max_sleep_secs for _ in range(secs_int)]
        if secs_decimal_remainder:
            chunks.append(int(str(secs_decimal_remainder).lstrip('0')))

        if secs_extra_ms:
            chunks.append(secs_extra_ms)

        if DEBUG:
            print(f"Debug [sweet_dreams]: -> Total: {secs} | Max: {max_sleep_secs} | Chunks: {chunks}")
            quit()

        for seconds in chunks:
            time.sleep(seconds)
    else:
        if DEBUG:
            print(f"Debug [sweet_dreams]: -> Total: {secs} | Max: {max_sleep_secs} | Chunks: None")
            quit()

        time.sleep(secs)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接