2016-04-01 5 views
0

私は次のPythonコードを実行していgevent.joinall:上記からわかるようになぜPythonはすべてgreenlets

>>> import gevent 
>>> from gevent import monkey; monkey.patch_all() 
>>> 
>>> def fooFn(k): 
...  return 'gevent_'+k 
... 
>>> threads = [] 
>>> threads.append(gevent.spawn(fooFn,'0')) 
>>> threads.append(gevent.spawn(fooFn,'1')) 
>>> 
>>> gevent.joinall([threads[1]]) 
>>> 
>>> print threads[1].value 
gevent_1 
>>> print threads[0].value 
gevent_0 
>>> 

を、threads[0].valuefooFnから適切な値を得ました。つまり、threads[0]苗字が実行されたことを意味します。

threads[1]野菜をgevent.joinallに渡したのはなぜですか?

実際にgevent.joinallに渡されるグリーンレットだけが実行されるようにするにはどうすればよいですか?

+0

'gevent.joinall()'は、完了するためにパラメータとして渡されたグリーンレットを待って、メインスレッドと結合します。私の知る限りでは、他のスレッドの実行をブロックしません。グリーンレットの実行が終了するまで、メインスレッドに終了しないように指示します。 –

答えて

3

greenlet.spawn()に電話すると、ごちゃごちゃはすぐにになります。つまり、spawn()に電話をかけたときに作成され、すぐに開始されます。そういうわけで、最初のグリーンレットは走っているのです - 両方のグリーンレットがあなたがそれらを産んだ瞬間から実行していて、あなたがグリーンレット1の結果を調べるまでに両方とも実行されました。

gevent.joinall()は、グリーンレットを実行しません。メインスレッド(実際にはspawnを編集したもの)だけが、パラメータとして渡されたものが実行を終了するまで待機するように指示します。 joinallを呼び出さないと、joinall()にある未処理の結果に達する前にメインスレッドが終了して終了するリスクがあります。その後、その結果を誰が処理するのでしょうか?あなたではなく、スクリプトからよりも、コンソールREPLでjoinall()と呼ば

  • :ここ

    は、あなたはあなたが望むようgevents振る舞いを見るために変更する必要がある二つのことをしました。ここで

    、メインスレッド - REPLは - あなたがexit() を呼び出すか、EOFを示しているときREPLのみ終了しているため、 greenletsが戻る前にが完了していないことが保証です。しかし、即座のユーザーのやりとりがないスクリプトでは、その贅沢はありません。実行するスクリプトが残っていないときに実行が終了します。だから、我々はjoin()と呼んで、メインスレッドが終了せず、返される親なしであなたのグリーンレットをぶら下げさせるようにしているのです。

    (あなたが保証をしたい場合、あなたは次のgreenlet上の関数を呼び出すとき、それは良いアイデアだgreenletから結果があるでしょうが)コンソールでjoinall()を呼び出すにはポイントが

  • はあなたがそこshouldnませんグリーンレット2だけではなく、グリーンレット1のみが実行されることを保証したい場合は、spawn()と呼ばれています。その代わり、read what the docs say

    )、新しいgreenletを開始 Greenletコンストラクタにターゲット関数とその引数を渡すと(スタートを呼び出すには:

    >>> g = Greenlet(myfunction, 'arg1', 'arg2', kwarg1=1)

    >>> g.start()

    やクラスメソッドを使用します同じことをするショートカットであるspawn()

    0123この時点で実行を開始する必要がありgreenletを示すためにstartを使用し

は良いアイデアです。したがって、2つのgreenletオブジェクトを作成し、そのうちの1つにstartを呼び出して、その1つだけを実行します。

関連する問題