TAKEO

TAKEO

Python threading入門

はじめに

pythonのthreadingを使った並行処理を実装して見ましょう。

本記事ではスレッドを使うことで20秒かかる処理を10秒に短縮します。

20秒かかる処理

次のスクリプトを実行すると20秒程度かかると思います。関数f1、f2の処理にそれぞれ10秒かかるので

  1. f1を実行する
  2. f2を実行する

というように順次処理を行うため、合計20秒かかってしまいます。

逐次処理

sample.py
Copied!!
import time

def f1():
    for i in range(10):
        print(f"f1 index={i}")
        time.sleep(1)

def f2():
    for i in range(5):
        print(f"f2 index={i}")
        time.sleep(2)

def main():
    startTime = time.time()
    f1()
    f2()
    endTime = time.time()
    print(f"処理時間:{endTime-startTime}秒")

if __name__ == "__main__":
    main()

スレッドを使って処理時間を短縮しよう

  1. threadingモジュールをimportします

    Copied!!
    import threading
    
  2. スレッドで実行したい関数を引数targetに渡します

    Copied!!
    threads = [
        threading.Thread(target=f1),
        threading.Thread(target=f2),
    ]
    
  3. startでスレッドの処理を開始します

    Copied!!
    for t in threads:
        t.start()
    
  4. joinでスレッドの処理が完了するのを待ちます

    Copied!!
    for t in threads:
        t.join()
    
  5. 完成形

    thread.py
    Copied!!
    import threading
    import time
    
    def f1():
        for i in range(10):
            print(f"f1 index={i}")
            time.sleep(1)
    
    def f2():
        for i in range(5):
            print(f"f2 index={i}")
            time.sleep(2)
    
    def main():
        threads = [
            threading.Thread(target=f1),
            threading.Thread(target=f2),
        ]
    
        startTime = time.time()
        for t in threads:
            t.start()
    
        for t in threads:
            t.join()
    
        endTime = time.time()
        print(f"処理時間:{endTime-startTime}秒")
    
    if __name__ == "__main__":
        main()
    

なぜ実行時間を短縮できるのか

thread.pyを実行すると10秒程度で処理が終了したと思います。

Copied!!
$ python3 thread.py
f1 index=0
f2 index=0
f1 index=1
f2 index=1
f1 index=2
f1 index=3
f2 index=2
f1 index=4
f1 index=5
f2 index=3
f1 index=6
f1 index=7
f2 index=4
f1 index=8
f1 index=9
処理時間:10.012817621231079秒

スレッドを使うとf1とf2の処理は交互に実行されます。上のログを見ると次のような順番で関数f1、f2が実行されたことがわかります。

  1. f1のfor文の1周目を実行。
  2. f2のfor文の1周目を実行。
  3. f1のfor文の2周目を実行。
  4. f2のfor文の2周目を実行。

これより、f1のsleepで指定した時間を待たずにf2が実行され、また、f1はf2のsleepの影響を受けずに処理を進めていることがわかります。つまり、f1とf2をそれぞれ並行して実行しているため、処理時間を10秒程度に短縮することができています。

スレッド

まとめ

本記事ではスレッドを使った並行処理について紹介しました。スレッドを使うことでスクリプトの実行時間を短縮できることを直に感じていただけたかと思います。

関連記事