【问题标题】:How to avoid busy waiting for code that has no blocking calls?如何避免忙于等待没有阻塞调用的代码?
【发布时间】:2015-10-25 13:34:56
【问题描述】:

在编写while True 循环(在某些情况下无能为力)时,避免大量 CPU 使用的最佳方法是什么?好像time.sleep(0)伤害了CPU:

import time

msg = []

# in main thread I will add messages to msg list sometimes
msg.append('some_msg')

# in some other thread I will parse them like this:
while True:
  for msg in msgs:
    # do some operations
  time.sleep(0) # hurt CPU in case of len(msg) == 0

是的,我可以使用time.sleep(1) 代替它,但它真的是在 Python 中最正确的方法吗?

【问题讨论】:

  • 你为什么要这样做?
  • time.sleep(0) 在这里毫无意义,因为它没有做任何有用的事情,它只是调用一大堆依赖于平台的代码(因此,浪费资源),仅此而已。
  • 指定的链接不包含此问题的任何真实答案,请重新打开我的问题
  • 在这种情况下调用 sleep() 的原因是允许其他线程在您的消息循环等待消息时运行。您应该将睡眠时间设置为您可以接受的值。如果您的应用需要在十分之一秒内响应消息,请使用 sleep(0.05) 并将 cpu 释放给其他进程,同时等待消息到达。
  • 执行此操作的“正确”方法取决于您的 msgs 变量实际添加/删除的内容/方式。当您“处理”一条消息时,它会被丢弃吗?在我们为您提供帮助之前,您需要提供有关您的具体问题的更多信息。

标签: python


【解决方案1】:

这只是一个经典的生产者消费者问题,你一定在寻找比你做的更好的实现。

在您的情况下,如果您对 sleep 使用正值,那么您已经完成了为其他进程节省 CPU 以使用它的操作,因为高 CPU 使用率很好(为清楚起见,请参阅底部的注释)。

如果您正在寻找优化和更好的性能,那么您需要针对您的应用程序需求调整您的代码,这里有两个建议。

  1. 如果可以将msg 转换为线程安全队列,则可以使用wait and notify 调用在线程中使用信号(也称为线程间通信);这样你就可以克服任意等待。

  2. 1234563 /p>

注意:如果您的 CPU 使用率很高,则意味着您正在最好地使用您的计算资源,但这可能会导致可靠性下降和其他进程的资源匮乏,这可能很糟糕,因此请尝试优先考虑您的线程/进程根据您的需要。

【讨论】:

  • 使用睡眠进行轮询几乎总是错误的,在这种情况下几乎可以确定。由于代码不消耗任何内容,并且 OP 明确拒绝澄清,因此没有有效的答案。这就是你遇到不好的问题。 (±0)。
  • @msw 是的,使用睡眠进行轮询是一种残酷的方式,但它很简单,很多人都在使用它,这就是为什么我建议使用事件循环和线程安全队列的原因。
  • @msw 进一步因为它已经被提到它正在使用的非阻塞调用然后使用 event-loop 并没有提供任何更好的吞吐量它只会防止饥饿,我最好的选择是使用waitnotify 这样当msgs 结束时,CPU 可以做得更好。
  • 同意。我会将这个答案解读为“如果 OP 提出了更好的要求,这是对异步方法的一个很好的说明”。
【解决方案2】:

您使用了错误的数据类型。不为线程间通信创建列表。使用队列。 get-方法被阻塞。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-17
    • 1970-01-01
    • 1970-01-01
    • 2014-12-04
    • 2013-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多