19

コメントの私の質問から、「ネストされたWebリクエストを持つGeventプール」へのこの回答への回答に続きます。

多数のタスクがあると仮定すると、gevent プールと pool.spawn(...) を使用して同時実行数を制限するのではなく、gevent.spawn(...) を使用してすべてのタスクを同時に生成することの欠点はありますか?グリーンレット?

異なる定式化: 解決する問題で必要とされていなくても、gevent.Pool で「同時実行を制限する」ことに利点はありますか?

この問題の「多数」を構成するものは何ですか?

4

2 に答える 2

21

たくさんのものを扱うとき、それはただよりクリーンで良い習慣です。数週間前、gevent spawn を使用して DNS に対して 30k のオーダーで大量の電子メールを検証していたときに、これに遭遇しました :)。

from gevent.pool import Pool
import logging
rows = [ ... a large list of stuff ...]
CONCURRENCY = 200 # run 200 greenlets at once or whatever you want
pool = Pool(CONCURRENCY)
count = 0

def do_work_function(param1,param2):
   print param1 + param2

for row in rows:
  count += 1 # for logging purposes to track progress
  logging.info(count)
  pool.spawn(do_work_function,param1,param2) # blocks here when pool size == CONCURRENCY

pool.join() #blocks here until the last 200 are complete

私のテストでは、CONCURRENCY が​​約 200 のとき、マシンの負荷が EC2 m1.small で約 1 になることがわかりました。少し素朴にやりましたが、もう一度やるとしたら、複数のプールを実行し、それらの間でしばらくスリープして、NIC と CPU の負荷をより均等に分散しようとします。

心に留めておくべき最後のことは、開いているファイルに目を光らせ、必要に応じてそれを増やすことです: http://www.cyberciti.biz/faq/linux-increase-the-maximum-number-of-open-files。私が実行していた greenlet は、greenlet ごとに約 5 つのファイル記述子を占有していたので、注意しないとすぐに不足してしまう可能性があります。システムの負荷が 1 を超えている場合、これは役に立たない可能性があります。

于 2013-11-07T02:11:55.920 に答える
11

Google からここに来て、いくつかの簡単なテストを実行して、増加するNgreenlet を生成することにしました。仲間の検索者に役立つ可能性があるため、結果を共有します。

# 1 greenlet
real    0m1.032s
user    0m0.017s
sys     0m0.009s

# 100 greenlets
real    0m1.037s
user    0m0.021s
sys     0m0.010s

# 1,000 greenlets
real    0m1.045s
user    0m0.035s
sys     0m0.013s

# 10,000 greenlets
real    0m1.232s
user    0m0.265s
sys     0m0.059s

# 100,000 greenlets
real    0m3.992s
user    0m3.201s
sys     0m0.444s

したがって、最大 1,000 個の greenlet とパフォーマンスの低下はわずかですが、10,000 個以上の greenlet に到達し始めると、すべてが遅くなります。

テストコード:

import gevent

N = 0

def test():
    gevent.sleep(1)

while N < 1000:
  N += 1
  gevent.spawn(test)

gevent.wait()
于 2014-12-20T23:22:31.287 に答える