【问题标题】:Python: Pass or Sleep for long running processes?Python:长时间运行的进程通过还是休眠?
【发布时间】:2010-10-06 10:54:41
【问题描述】:

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

而真: 经过

而真: 时间.sleep(1)

哪一个对系统的影响最小?什么都不做但保持 Python 应用程序运行的首选方法是什么?

【问题讨论】:

  • 正确的答案是根本不做轮询I/O。例如,请参阅 select() 调用,操作系统会在此休眠,直到有内容可供读取。
  • 在线程的情况下,它们使用阻塞 TCP 连接等待消息。它只是我关心的主线程,它除了处理命令行选项、读取配置和线程启动之外什么都不做。

标签: python


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我想 time.sleep() 对系统的开销会更少。使用 pass 将导致循环立即重新评估并锁定 CPU,而使用 time.sleep 将允许暂时暂停执行。

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

    >>> while True:
    ...     pass
    ... 
    

    您可以看到 Python 立即开始消耗 90-100% 的 CPU,而不是:

    >>> import time 
    >>> while True:
    ...     time.sleep(1)
    ... 
    

    几乎没有在活动监视器上注册(这里使用 OS X,但每个平台都应该相同)。

    【讨论】:

    • 谢谢,我认为是这种情况,但我一直看到文档传递。
    • 天啊!谢谢你的这个......测试?我什至都懒得做这个小测试,现在我知道为什么我的双线程会消耗这么多 CPU。
    • while True: time.sleep(1000)哈哈!
    【解决方案3】:

    您并没有为您真正在做什么提供太多背景信息,但也许可以使用Queue 来代替显式的忙等待循环?如果不是,我认为sleep 会更可取,因为我相信它会消耗更少的 CPU(正如其他人已经指出的那样)。

    [根据下面评论中的附加信息进行编辑。]

    也许这很明显,但无论如何,在您从阻塞套接字读取信息的情况下,您可以做的是让一个线程从套接字读取并将适当格式的消息发布到 @ 987654324@,然后让其余的“工作”线程从该队列中读取;然后工作人员将阻止从队列中读取,而不需要pass,也不需要sleep

    【讨论】:

    • 感谢关于 Queue 的提示看起来很方便,在这个应用程序中,我使用阻塞套接字来侦听来自 AMQP 代理的消息(在单独的线程中)并在收到后对它们进行操作。
    • @Crad:然后使用 select 等待套接字,类似于队列的工作方式。不要使用忙等待或轮询。
    【解决方案4】:

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

    所以

    # store the threads you start in a your_threads list, then
    for a_thread in your_threads:
        a_thread.join()
    

    见:thread.join

    【讨论】:

    • 不过,我不希望线程完成。这是一个永无止境的过程。这个逻辑还适用吗?
    • 当然逻辑仍然适用。您甚至可以避免浪费几个周期进行“循环”睡眠。
    • 这似乎不起作用,因为线程不应该终止进程被终止,超时在概念上总是首先出现,或者我错过了什么?
    • @Crad -- 什么超时?主线程永远等待孩子。这就是主线程所做的。
    • @Crad:在我的示例代码中,我没有指定任何超时,因此连接将永远等待。你有理由自己指定一个吗?
    【解决方案5】:

    在 Python 中将方法作为具有睡眠的后台线程运行

        import threading
        import time
    
    
        class ThreadingExample(object):
            """ Threading example class
            The run() method will be started and it will run in the background
            until the application exits.
            """
    
            def __init__(self, interval=1):
                """ Constructor
                :type interval: int
                :param interval: Check interval, in seconds
                """
                self.interval = interval
    
                thread = threading.Thread(target=self.run, args=())
                thread.daemon = True                            # Daemonize thread
                thread.start()                                  # Start the execution
    
            def run(self):
                """ Method that runs forever """
                while True:
                    # Do something
                    print('Doing something imporant in the background')
    
                    time.sleep(self.interval)
    
        example = ThreadingExample()
        time.sleep(3)
        print('Checkpoint')
        time.sleep(2)
        print('Bye')
    

    【讨论】:

      【解决方案6】:

      如果您正在寻找一种短的、零 CPU 的方式来永久循环直到键盘中断,您可以使用:

      from threading import Event
      
      Event().wait()
      

      注意:由于a bug,这仅适用于 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...')
      

      哪些打印:

      Task complete.
      Continuing...
      

      【讨论】:

      • 请注意,这适用于 Linux 和 Mac,但在 Windows 上,KeyboardInterrupt 将不会中断 event.wait()。如果指定了等待超时,则异常将在超时结束时引发,但如果没有给出,则 event.wait() 将永远阻塞。在 Windows 上,SIGINT 中断睡眠,所以这是更好的实现。我还没有在任何地方看到这个文档,但这是我在测试(Python 3.7)方面的经验。我在这里找到了一个相关的线程:stackoverflow.com/questions/39545612/…
      • @joshstaiger 很有趣。我已经更新了帖子。我确实发现由于 Python 2 中的一个错误,它不起作用,但我从未猜到它不适用于 Windows 3.2+。
      【解决方案7】:

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

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

      【讨论】:

        猜你喜欢
        • 2011-08-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-14
        • 1970-01-01
        • 2021-03-17
        • 2015-12-11
        相关资源
        最近更新 更多