ラブびあ

ビール。ときどきラブ

Pythonで非同期処理

Pythonでマルチプロセスまたはマルチスレッドによる非同期処理を実装する方法を調べました。ここでは、典型的なバッチ処理(prepareが処理対象イテレータ、executeはprepareの要素ごとに呼び出す処理)で、async/awaitを実装していないexecute処理を非同期化してみます。サンプルでは並行数を「3」としています。

サンプルコード
import asyncio
import time

def now():
    return time.strftime('%X')

def prepare():
    return [
        ('A', 1),
        ('B', 1.3),
        ('C', 1.6),
        ('D', 1.9),
        ('E', 2.2),
    ]

def execute(name, sec):
    for i in range(3):
        print(name + '>' + now())
        time.sleep(sec)
        print(name + '<' + now())

def run():
    loop = asyncio.get_event_loop()

    async def _run_tasks(its, limit):
        sem = asyncio.Semaphore(limit)

        async def _run_task(args):
            async with sem:
                return await loop.run_in_executor(None, execute, *args)

        return await asyncio.gather(*[_run_task(it) for it in its])

    loop.run_until_complete(_run_tasks(prepare(), 3))

print('--' + now())
run()
print('--' + now())
結論

loop.run_in_executor() を使うと、どんな処理でも並列化できる!


本家サイトはこちら
docs.python.org

ここに記載したコードは下記サイトで動作確認しました。
www.jdoodle.com