pythonでマルチスレッド

pythonのコード上でマルチスレッドで実行したいことがあって調べたのでメモ。

もうつべこべ言わず、これがすべて!

import concurrent.futures
import time

def func1(a, b):
   print("func1(%d, %d)" % (a,b) )
   
   time.sleep(1)
   return a+b

if __name__ == "__main__":
   executor = concurrent.futures.ThreadPoolExecutor(max_workers=5)
   
   rets = [executor.submit(func1, i*10, 1) for i in range(8)]
   
   s = 0
   for ret in concurrent.futures.as_completed(rets):
       print('1つおわった%d' % ret.result())
       s += ret.result()
   
   print('全部おわり!%d' % s)
   # 全部おわり!288

ポイントは3つくらい。

①ThreadPoolExecutorで実行用のインスタンスを作成する。これは、マルチスレッド群をまとめる親分的存在。max_workers指定をすると、この数までしかマルチしない。

②executor.submitで実行。そのとき関数に渡す引数は、関数名に続いて渡す。submitの戻り値は「Future」というオブジェクト。呼ばれた瞬間にfunc1が起動される。max_workers=5の場合は6個目の起動は、1個目が終わるまで待たされる。

③Futureを配列につめ、as_completedに配列を渡す。ここでは、1つのスレッドが終わるごとにforが1回回る。つまり6回目が動くときに"1つおわった"が出る。(たぶ6回目の起動の方が一瞬速いけど、そのことは利用しない方がよさげ。)

④関数の戻り値は、ret.result()で取得。

⑤ループが8回回り切ったら、”全部おわり”のprintを通る。それまで通らない。

5つあった。見積もり精度悪し。

この記事が気に入ったらサポートをしてみませんか?