2015-12-28 18 views
15

実行中のasyncioループにどのように新しいコルーチンを追加できますか?つまり既にコルーチンのセットを実行している人。実行中のasyncioループにコルーチンを追加する方法は?

回避策として、既存のコルーチンが完了するのを待ってから、新しいループ(コルーチンを追加して)を初期化することができます。しかし、より良い方法がありますか?

答えて

9

新しいコルーチンをスケジューリングするためにcreate_taskを使用することができます。

import asyncio 

async def cor1(): 
    ... 

async def cor2(): 
    ... 

async def main(loop): 
    await asyncio.sleep(0) 
    t1 = loop.create_task(cor1()) 
    await cor2() 
    await t1 

loop = asyncio.get_event_loop() 
loop.run_until_complete(main(loop)) 
loop.close() 
+2

努力をありがとう、しかし限り、私は理解して、この答えは間違っています。ここでは 'main'を最初に起動するとコルーチンが作成され、その後にループが始まります。つまり、この例では、ループが開始する前にコルーチンをスケジュールしています。私が求めたものではありません。 – Petri

+0

'main'は単にラッパーとして存在します。私はちょうど 'loop.create_task'の使い方を指摘したかったのです。 'create_task'はあなたが望むものとまったく同じです。 - この例を編集して、 'main'が' create_task'を実行する前にブロックすることを明確にしました。 –

7

あなたの質問は非常に近い「プログラムを実行する関数呼び出しを追加する方法は?」

正確に新しいコルーチンをイベントループに追加する必要があるときは、

いくつかの例を見てみましょう。ここでは並列2つのコルーチンとイベントループを起動するプログラム:

import asyncio 
from random import randint 


async def coro1(): 
    res = randint(0,3) 
    await asyncio.sleep(res) 
    print('coro1 finished with output {}'.format(res)) 
    return res 

async def main(): 
    await asyncio.gather(
     coro1(), 
     coro1() 
    ) # here we have two coroutines running parallely 

if __name__ == "__main__": 
    loop = asyncio.get_event_loop() 
    loop.run_until_complete(main()) 

出力:

coro1 finished with output 1 
coro1 finished with output 2 
[Finished in 2.2s] 

あなたがcoro1の結果を取ると、いくつかのコルーチンを追加して、すぐにそれは準備ができて、それを使用する必要があることができますか?その場合、ただcoro1を待つコルーチンを作成し、値を返すだ使用します。

import asyncio 
from random import randint 


async def coro1(): 
    res = randint(0,3) 
    await asyncio.sleep(res) 
    print('coro1 finished with output {}'.format(res)) 
    return res 

async def coro2(): 
    res = await coro1() 
    res = res * res 
    await asyncio.sleep(res) 
    print('coro2 finished with output {}'.format(res)) 
    return res 

async def main(): 
    await asyncio.gather(
     coro2(), 
     coro2() 
    ) # here we have two coroutines running parallely 

if __name__ == "__main__": 
    loop = asyncio.get_event_loop() 
    loop.run_until_complete(main()) 

出力:

coro1 finished with output 1 
coro2 finished with output 1 
coro1 finished with output 3 
coro2 finished with output 9 
[Finished in 12.2s] 

を特定の構文との定期的な機能についてなどコルーチン考えてみてください。並列に実行する関数をいくつか起動することができます(asyncio.gather)。最初に実行した後に次の関数を開始できます。他の関数を呼び出す新しい関数を作成できます。

+3

コルーチンは並列*ではなく*並列実行*。全く同じことではありません。 –

4

あなたが使用することができ、すでに実行中のイベントループに機能を追加するには:私の場合は、asyncioと一緒にマルチスレッディング(threading)を使用していることをイベントループにタスクを追加したいた

asyncio.ensure_future(my_coro())

すでに稼働していた同じ状況の他の人は、明示的にイベントループを記述してください(Threadの中には存在しないので)。すなわち:グローバルスコープで

:次に

event_loop = asyncio.get_event_loop() 

後に、あなたのThread内側:

asyncio.ensure_future(my_coro(), loop=event_loop) 
関連する問題