如何无限期地干净地睡觉?

时间:2018-05-07 14:44:53

标签: python python-3.x sleep thread-sleep

在我的代码中启动了一些线程,我需要在脚本结束时无限期地睡眠,而这种睡眠不会成为性能 1 的重大打击。

一种可能性是短暂睡眠无限循环:

while True:
    time.sleep(1)

或睡了很长时间

time.sleep(4000000)

import signal
signal.pause()

可是:

  • 我没有找到睡眠会接受的最长时间(sys.maxint太大了)

  • signal.pause()仅在Unix中实现

  • 和第一个"睡眠循环"看起来不干净(为什么1秒而不是10,或0.1?)

是否有一种干净,pythonic的无限期睡眠方式?

1 我不直接控制线程,否则我会去threading.Thread.join(),因为线程本身不会结束。

1 个答案:

答案 0 :(得分:3)

threading.enumerate为您提供包括主要线程在内的所有正在运行的线程的列表,因此您可以这样做:

main_thread = threading.main_thread()
while True:
    L = threading.enumerate()
    L.remove(main_thread)  # or avoid it in the for loop
    for t in L:
        t.join()

如果您的库在等待当前的线程完成时创建新线程,则需要while True

假设在enumerate运行时没有创建线程,您可以检查L是否只有一个元素(主线程),如果是,则打破循环。这与Tadhg McDonald-Jensen使用suggestioniter sets以及哨兵相结合,结果是:

main_thread = threading.main_thread()
main_threads = [main_thread, ]  # WARN: can't have more than one thread here
for threads in iter(threading.enumerate, main_threads):
    for t in threads:
        if t == main_thread:
            continue
        t.join()

enumerate以未定义的顺序返回列表,因此如果您有多个“主”线程,则订单开始重要。解决方案是使用EAFP,即main_threads = {main_thread, }iter(lambda : set(threading.enumerate()), main_threads)

如果您更喜欢https://github.com/llSourcell/tensorflow_chatbot请求原谅而非权限的方法,并且当您到达脚本结束时所有线程都已启动,您也可以这样做:

for thread in threading.enumerate():
    try:
        thread.join()
    except RuntimeError:
        # trying to join the main thread, which would create a deadlock (see https://docs.python.org/3/library/threading.html#threading.Thread.join for details)
        pass