【问题标题】:Better solution for Python Threading.Event semi-busy waitingPython Threading.Event 半忙等待的更好解决方案
【发布时间】:2012-03-31 07:53:40
【问题描述】:

我正在使用非常标准的 Threading.Event: 主线程到达一个循环运行的点:

event.wait(60)

其他人阻止请求,直到回复可用,然后启动:

event.set()

我希望主线程选择 40 秒,但事实并非如此。 来自 Python 2.7 源代码 Lib/threading.py:

# Balancing act:  We can't afford a pure busy loop, so we
# have to sleep; but if we sleep the whole timeout time,
# we'll be unresponsive.  The scheme here sleeps very
# little at first, longer as time goes on, but never longer
# than 20 times per second (or the timeout time remaining).
endtime = _time() + timeout
delay = 0.0005 # 500 us -> initial delay of 1 ms
while True:
   gotit = waiter.acquire(0)
   if gotit:
       break
   remaining = endtime - _time()
   if remaining <= 0:
       break
   delay = min(delay * 2, remaining, .05)
   _sleep(delay)

我们得到的是每 500us 运行一次选择系统调用。 这会在具有非常紧密的选择循环的机器上造成明显的负载。

有人能解释一下为什么涉及到平衡行为,为什么它与等待文件描述符的线程不同。

其次,有没有更好的方法来实现一个大部分处于休眠状态的主线程而没有如此紧密的循环?

【问题讨论】:

    标签: python multithreading python-2.7 events busy-loop


    【解决方案1】:

    我最近遇到了同样的问题,我还追踪到了 threading 模块中的这段代码。

    很烂。

    解决方案是重载线程模块,或者迁移到python3,这部分实现已经修复。

    在我的情况下,迁移到 python3 将是一项巨大的努力,所以我选择了前者。我所做的是:

    1. 我创建了一个带有pthread 接口的快速.so 文件(使用cython)。它包括调用相应pthread_mutex_* 函数的python 函数,以及针对libpthread 的链接。具体来说,与我们感兴趣的任务最相关的函数是pthread_mutex_timedlock
    2. 我创建了一个新的threading2 模块,(并用import threading2 替换了我的代码库中的所有import threading 行)。在threading2 中,我重新定义了来自threading 的所有相关类(LockConditionEvent),以及来自Queue 的那些我经常使用的类(Queue 和@987654339 @)。 Lock 类完全使用 pthread_mutex_* 函数重新实现,但其余的要容易得多——我只是将原来的子类化(例如 threading.Event),并覆盖 __init__ 以创建我的新 Lock 类型。其余的工作正常。

    新的Lock 类型的实现与threading 中的原始实现非常相似,但我基于python3threading 模块中找到的代码(这自然比上面提到的“平衡行为”块要简单得多)。这部分相当简单。

    (顺便说一句,在我的案例中,我的大规模多线程进程的速度提高了 30%。甚至超出了我的预期。)

    【讨论】:

      【解决方案2】:

      我完全同意你的观点,这很蹩脚。

      目前,我坚持使用简单的选择调用,没有超时,并监听之前创建的管道。 唤醒是通过在管道中写入一个字符来完成的。

      查看来自 gunicorn 的 sleepwakeup 函数。

      【讨论】:

        猜你喜欢
        • 2011-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多