なんだかGoodVibes

日々の勉強メモです。

【Python】スレッドを使用した並列処理(threading)

こんにちは。
本日はPythonメモです。

概要

Pythonでは通常、上から順に処理が実行されます。
時間がかかったり重い処理を行う場合、
上から順に処理を行うのでは効率が悪い場合があります。

その場合、並列処理で分散させて処理を行うと
効率よく処理できます。

Pythonでは、threadingモジュールを使用することで
並列処理を実装できます。

import threading


スレッドを使用した並列処理

まず、通常の処理の場合を見てみます。

import time

def heavy_proc():
    print('時間のかかる処理開始...')
    time.sleep(3)
    print('時間のかかる処理終了!')

print('Start!')
heavy_proc()
print('End.')

出力は以下のようになります。

Start!
時間のかかる処理開始...
時間のかかる処理終了!
End.

heavy_procの処理が完了するのを待機してから
「End.」が出力されます。

この処理を並列処理に書き換えると以下のようになります。

import time
import threading

def heavy_proc():
    print('時間のかかる処理開始...')
    time.sleep(3)
    print('時間のかかる処理終了!')

print('Start!')
t = threading.Thread(target=heavy_proc)
t.start()
print('End.')

以下の処理でスレッドオブジェクトを生成しています。

t = threading.Thread(target=heavy_proc)

start()で処理を開始します。

実行結果は以下のようになります。

Start!
時間のかかる処理開始...
End.
時間のかかる処理終了!

「End.」の出力が待機せず出力されます。


スレッドの待機(join)

並列処理で処理を実行するけども
スレッドを待機したい。。。
その場合は、join()を使用します。

import time
import threading

def heavy_proc():
    print('時間のかかる処理開始...')
    time.sleep(3)
    print('時間のかかる処理終了!')

print('Start!')
t = threading.Thread(target=heavy_proc)
t.start()
t.join()
print('End.')

実行結果は以下です。

Start!
時間のかかる処理開始...
時間のかかる処理終了!
End.

heavy_procが完了してから「End.」が出力されます。


引数を渡す

引数を渡す場合は、スレッドオブジェクトを生成する際に
argsに指定します。

argsにはタプルを指定します。

import time
import threading

def heavy_proc1(name):
    print(f'[{name}] 時間のかかる処理開始...')
    time.sleep(3)
    print(f'[{name}] 時間のかかる処理終了!')

def heavy_proc2(name, no):
    print(f'[{name}:{no}] 時間のかかる処理開始...')
    time.sleep(5)
    print(f'[{name}:{no}] 時間のかかる処理終了!')

print('Start!')
t1 = threading.Thread(target=heavy_proc1, args=('thread1',))
t1.start()

t2 = threading.Thread(target=heavy_proc2, args=('thread2', 100))
t2.start()

t1.join()
t2.join()

print('End.')

実行結果は以下です。

Start!
[thread1] 時間のかかる処理開始...
[thread2:100] 時間のかかる処理開始...
[thread1] 時間のかかる処理終了!
[thread2:100] 時間のかかる処理終了!
End.



以上です。