gpt4 book ai didi

python - Python Threading.Event半忙等待更好的解决方案

转载 作者:太空狗 更新时间:2023-10-29 21:50:43 25 4
gpt4 key购买 nike

我使用的是非常标准的 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)

我们得到的是每 500 微秒运行一次选择系统调用。这会给机器带来明显的负载,并且选择循环非常紧凑。

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

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

最佳答案

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

这很糟糕。

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

就我而言,迁移到 python3 需要付出巨大的努力,所以我选择了前者。我所做的是:

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

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

(顺便说一句,在我的案例中,结果是我的大规模多线程进程加速了 30%。甚至超过了我的预期。)

关于python - Python Threading.Event半忙等待更好的解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9709022/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com