🏏

Pythonでスレッドで並列実行

2022/05/25に公開

はじめに

Pythonでスレッドで並列実行する場合の個人的なテンプレになります。
スレッドを使わないといけないような処理はPythonあまり実装することはないのですがたまに使います。
並列実行する場合は、プロセス自体を複数にすることが多いです。

内容

test.py
import concurrent.futures
import threading
import traceback
import time

test_list = []

lock_A = threading.Lock()
max_workers = 8
def run_by_thread_A(p,lock):
    # ローカル関数でも可能
    try:
        [n,t] = p
        thread_name = threading.currentThread().getName()
        ret = "by Thread. p={0}/{1} : {2}".format(n,t,thread_name)
        time.sleep(0.1)
        with lock:
            test_list.append(ret)
            
    except Exception as e:
        traceback.print_exc()
        exit(100)

    return ret
    
# 依頼パラメータの作成
work_items = [
    [0,"TEST-A"],
    [1,"TEST-B"],
    [2,"TEST-C"],
    [3,"TEST-D"],
    [4,"TEST-E"],
]

with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
    futures = [executor.submit(run_by_thread_A,i,lock_A) for i in work_items]
    
# スレッドの終了待機はwithが実施しているのでこの時点で全部のスレッドが終了している。
# 結果をまとめて取得する。
for f in futures:
    print(f"result = {f.result()}")
    
print(test_list)

説明

  • run_by_thread_Aの内容を用途に合わせて修正する。
  • 例外発生時にexitするかどうかは都度調整する。
  • lock_Aは使わないことも多いが作成はしている。
  • 結果を直接リストに格納する場合などで利用している。
  • 一部の処理を並列実行するような利用で、常時複数が並列という用途では使わない。
  • その場合は他の言語を使っている。

注意点

  • CTRL+Cで停止が困難。

Discussion