Python:长时间运行进程的通过或休眠?

Gav*_*Roy 42 python

我正在编写一个队列处理应用程序,它使用线程来等待并响应要传递给应用程序的队列消息.对于应用程序的主要部分,它只需要保持活动状态.对于代码示例,例如:

while True:
  pass

要么

while True:
  time.sleep(1)

哪一个对系统的影响最小?什么是什么都不做,但保持python应用程序运行?

Jay*_*Jay 61

我认为time.sleep()将减少系统的开销.使用pass将导致循环立即重新评估并固定CPU,而使用time.sleep将允许执行暂时中止.

编辑:只是为了证明这一点,如果你启动python解释器并运行:

>>> while True:
...     pass
... 
Run Code Online (Sandbox Code Playgroud)

您可以观看Python立即开始吃掉90-100%的CPU,而不是:

>>> import time 
>>> while True:
...     time.sleep(1)
... 
Run Code Online (Sandbox Code Playgroud)

甚至几乎没有在Activity Monitor上注册(在这里使用OS X,但每个平台应该是相同的).

  • `while True: time.sleep(1000)` 哈哈! (2认同)

tzo*_*zot 27

为什么睡觉?你不想睡觉,你想等待线程完成.

所以

# store the threads you start in a your_threads list, then
for a_thread in your_threads:
    a_thread.join()
Run Code Online (Sandbox Code Playgroud)

请参阅:thread.join


Mat*_*eld 10

如果您正在寻找一种简短的零CPU方式来循环直到KeyboardInterrupt,您可以使用:

from threading import Event

Event().wait()
Run Code Online (Sandbox Code Playgroud)

注意:由于存在错误,这仅适用于Python 3.2+.此外,它似乎无法在Windows上工作.出于这个原因,while True: sleep(1)可能是更好的选择.

对于某些背景,Event对象通常用于等待长时间运行的进程完成:

def do_task():
    sleep(10)
    print('Task complete.')
    event.set()

event = Event()
Thread(do_task).start()
event.wait()

print('Continuing...')
Run Code Online (Sandbox Code Playgroud)

哪个印刷品:

Task complete.
Continuing...
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这适用于 Linux 和 Mac,但在 Windows 上,KeyboardInterrupt 不会*中断 event.wait()。如果指定了等待超时,则在超时结束时将引发异常,但如果没有给出,则 event.wait() 将永远阻塞。在 Windows 上, SIGINT * 将 * 中断睡眠,所以这是更好的实现。我没有在任何地方看到过这种记录,但这是我的测试经验(Python 3.7)。我在这里找到了一个相关的线程:/sf/ask/2768192871/ (2认同)

Ada*_*dam 10

signal.pause()是另一种解决方案,请参阅https://docs.python.org/3/library/signal.html#signal.pause

使进程休眠直到接收到信号;然后将调用适当的处理程序。什么都不返回。不在 Windows 上。(请参阅 Unix 手册页信号 (2)。)


her*_*n43 6

我一直看到/听说使用睡眠是更好的方法。使用 sleep 可以防止 Python 解释器的 CPU 使用率过高。


Joh*_*han 6

你没有为你真正做的事情提供太多的背景,但也许Queue可以使用而不是显式的忙等待循环?如果没有,我认为sleep会更好,因为我相信它会消耗更少的CPU(正如其他人已经注意到的那样).

[根据以下评论中的其他信息进行编辑.]

也许这是显而易见的,但无论如何,在你从阻塞套接字读取信息的情况下你可以做的是从套接字读取一个线程并将适当格式化的消息发布到a中Queue,然后让你的"工人"的其余部分从该队列中读取的线程; 然后,工作人员将阻止从队列中读取而不需要pass,也不需要sleep.