3

私が理解しているように、gevent のプールの考え方は、データベースや API などへの同時リクエストの総数をいつでも制限することです。

次のようなコードがあるとします。ここでは、Pool.

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番目のリクエストはいつ処理されますか?

4

1 に答える 1

7

プール クラスは、セマフォを使用してアクティブなグリーンレットを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()呼び出しを待機します。グリーンレットのいずれかが実行を終了するたびに、セマフォが解放されます。

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

したがって、あなたの場合、最初の 50 のリクエストのいずれかが完了するとすぐに、51 番目のリクエストが処理される (正確には開始される) ことを期待しています。

于 2013-01-15T15:49:28.793 に答える