Wait a moment...

備忘録 ーFutureを複数のThread/Taskで待ち受けー

27085
Namuyan
nem10.35xem (1)
266
0
2019-07-04 23:43:07
備忘録 ーFutureを複数のThread/Taskで待ち受けー

概要

Futureとは直訳で”未来”

並列処理でよく使われる概念で、”結果が格納される予定のオブジェクト”と考えて欲しいです。結果がでるまで別の処理をしよう、という事ですね。これの待ち受けにはLockが用いられますが、PythonのLockは低レベルAPIのはずなので想定外の操作をするとどうなるのかがわからないリスクがあります。

今回はこのFutureを複数の処理から待ち受けたい。しかし公式Docにはそのような事をしたらどうなるのか書かれていない。”できるだろう”の想定の元でコードを書いてしまうのもいいけれどバグったら怖いですよね?怖くない?あたま7payですよアナタ

そこでasynciothreadingで実験コードを書いてみました。

 

threadingのコード

from concurrent.futures import Future
import threading
from time import time, sleep


def sleeper(fut: Future, ntime):
    sleep(ntime)
    fut.set_result(True)
    print(time(), "OK1")


def waiter(fut: Future, ntime):
    sleep(ntime)
    print(time(), "waiting..")
    print(time(), "OK2", fut.result())


def main():
    future = Future()
    threading.Thread(target=sleeper, args=(future, 2.5)).start()
    for _ in range(30):
        threading.Thread(target=waiter, args=(future, 1.0)).start()
    print(time(), "OK3", future.result())


if __name__ == '__main__':
    main()

 

asyncioのコード

import asyncio
from time import time


loop = asyncio.get_event_loop()


async def sleeper(fut: asyncio.Future, ntime):
    await asyncio.sleep(ntime)
    fut.set_result(True)
    print(time(), "OK1")


async def waiter(fut: asyncio.Future, ntime):
    await asyncio.sleep(ntime)
    print(time(), "waiting..")
    await fut
    print(time(), "OK2", fut.result())


async def main():
    future = asyncio.Future()
    asyncio.ensure_future(sleeper(future, 2.5))
    for _ in range(30):
        asyncio.ensure_future(waiter(future, 1.0))
    await future
    print(time(), "OK3", future.result())


if __name__ == '__main__':
    loop.run_until_complete(main())

 

Note

コードとしては”30のTask/ThreadからFutureの待ち受けをする”というものです。threadingにおける処理単位がThread、asyncioにおける処理単位がTaskですが似たようなものと考えてもらってもOKです。

 

結論

結果として、どちらでも複数での待ち受けは問題ありません

timeを見比べるとasyncioの方が同じ数字が並んでいて効率の高さが垣間見られました。

PythonにはGILという難敵がいるので非同期IOの方が処理が効率的なのでしょう。

 

前の備忘録 https://nemlog.nem.social/blog/26227

この記事を書いた人
なーむやーんならねーそうならねー♪ 備忘録を不定期連載中