私はオブジェクトのリストを持っており、オブジェクトごとに非同期的な作業をする必要があります。どのようにPythonで同期オブジェクトの反復と非同期コードを組み合わせるには?
forループは同期であり、完全に進捗をブロックすると思いますか?もし私が、それを構築する方法?
私はオブジェクトのリストを持っており、オブジェクトごとに非同期的な作業をする必要があります。どのようにPythonで同期オブジェクトの反復と非同期コードを組み合わせるには?
forループは同期であり、完全に進捗をブロックすると思いますか?もし私が、それを構築する方法?
def run(tasks):
# ...
loop = asyncio.get_event_loop()
loop.run_until_complete(aysnc_wrapper())
通常、イベントループはグローバルで、スクリプト全体のメインエントリポイントとして起動する必要があります。同じように(単一の関数run
の内部でイベントループを実行する)、同じイベントループで他のコルーチンを上位コードが実行できなくなります。
あなたがこれを理解して、他の非同期のものと一緒に使うことができないrun
の機能をブロックしたい場合は、さらにお読みください。あなたのasync_wrapper
と
問題は、それが前のものが行われた後にのみ、次update_ocr_task()
コルーチンを待っていることです。 forループは、「ブロッキング」と呼ばれるものではありませんが、同時ではありません。非同期パラダイムによって提供される利点は使用されません。
asyncioを使用する利点を得るには、複数のコルーチンを同時に実行する必要があります。それを行うための一般的な方法は、asyncio.gather()を使用することです:
async def async_wrapper():
async def process_single_task(task):
resolver = aiohttp.AsyncResolver()
connector = aiohttp.TCPConnector(resolver=resolver, family=socket.AF_INET)
async with aiohttp.ClientSession(connector=connector) as session:
await session.get(...) # do all job for *single* local task here.
# Run multiple task processing coroutines concurrently:
await asyncio.gather(
*[process_single_task(t) for t in tasks]
)
あなたはまた、一般的にasyncioについてthis少し答えを読むことができますしたい場合。
ああ、私は何が間違っているのか気づいたと思う。 'await update_ocr_task()'は 'await task_manager.async_get_task_status(session、task)'のような他のコルーチンと同時ですが、それ自体ではありません。 'gather'はすべて' update_ocr_task'を同時に行います。そこが肝心だ。ところで、ループ全体を関数にラップする理由は、メインスレッドが同期タスクであるため、別のスレッド/プロセスで非同期イベントループを実行したいということです。 – Sraw
もう少しの質問ですが、 'for'を' async for'と置き換えて同じ振る舞いを達成することはできますか? – Sraw
@Sraw no。非同期ジェネレータによって反復するために 'async for'が使用されます。それは絶対に別のものです。 –