何时在Gevent中使用线程池?

16

我注意到Gevent有线程池对象。 有人能解释一下什么时候使用线程池以及何时使用常规池吗?gevent.threadpool和gevent.pool之间有什么区别?

1个回答

14

当您有一段需要很长时间运行(几秒钟)且不会导致绿色线程切换的 Python 代码时,所有其他 greenlet / gevent 作业都将“饥饿”并且没有计算时间,这看起来像您的应用程序“挂起”。

如果您将此“重”任务放入 Threadpool 中,线程化执行将确保其他 greenlet 不会“饥饿”。但是,我认为如果您的代码在 C 库中花费了很多时间,则不会产生影响。

以下是来自 gevent 的示例。请注意,该示例使用阻塞的 time.sleep 而非 gevent.sleep

提示: 如果您有一个需要很长时间运行的循环,那么您可以在循环中加入 gevent.sleep(0)。每个循环,其他 greenlets 都有机会运行。您的缓慢循环中的 gevent.sleep(0) 将确保其他 greenlet 不会“饥饿”,使应用程序显示为响应。

import time
import gevent
from gevent.threadpool import ThreadPool


pool = ThreadPool(3)
start = time.time()
for _ in xrange(4):
    pool.spawn(time.sleep, 1)
gevent.wait()
delay = time.time() - start
print 'Running "time.sleep(1)" 4 times with 3 threads. Should take about 2 seconds: %.3fs' % delay

“但我认为,如果你的代码在C库中花费了很多时间,它将没有影响”,你确定吗?你是指C扩展还是ctypes?因为如果你释放GIL(在C扩展中手动释放或者像ctypes一样自动释放),那么应用程序将从线程池中受益,不是吗? - MariusSiuram
如果你释放了GIL,我确切地说,我没有时间去弄清楚每个C库... - Stephan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接