产生比在gevent池中更多的线程

时间:2013-01-14 22:37:37

标签: pool gevent spawn

据我所知,gevent中池的想法是随时限制并发请求的总数,数据库或API等。

假设我有这样的代码,我会在Pool中产生比我有空间的更多greenlets:

import gevent.pool

pool = gevent.pool.Pool(50)
jobs = []
for number in xrange(300):
    jobs.append(pool.spawn(do_something, number))

total_result = [x.get() for x in jobs]

尝试生成第51个请求时的实际行为是什么?第51个请求何时处理?

1 个答案:

答案 0 :(得分:6)

池类使用信号量来计算活动的greenlet,在构造函数中使用size count初始化:

class Pool(Group):

    def __init__(self, size=None, greenlet_class=None):
        if size is not None and size < 1:
            raise ValueError('Invalid size for pool (positive integer or None required): %r' % (size, ))
        Group.__init__(self)
        self.size = size
        if greenlet_class is not None:
            self.greenlet_class = greenlet_class
        if size is None:
            self._semaphore = DummySemaphore()
        else:
            self._semaphore = Semaphore(size)

每次调用spawn()时,它都会尝试获取信号量:

    def spawn(self, *args, **kwargs):
        self._semaphore.acquire()
        try:
            greenlet = self.greenlet_class.spawn(*args, **kwargs)
            self.add(greenlet)
        except:
            self._semaphore.release()
            raise
        return greenlet

如果池已满,则被叫greenlet将等待_semaphore.acquire()调用。只要任何greenlet结束执行,就会释放信号量:

    def discard(self, greenlet):
       Group.discard(self, greenlet)
       self._semaphore.release()

因此,在您的情况下,我希望在前50个请求中的任何一个请求完成后立即处理(或开始,准确)第51个请求。