"も"日記

思考整理のためにいろいろ書き殴っていきます

【python】multiprocessとthreadを勉強したかった

業務で作成している生産管理ウェブシステムで、
入力された値を使って処理を実行するが、処理時間が長くなるので、
サーバー側での処理終了を待たずにユーザーにレスポンスを返す仕組みを実装したかった。

マルチプロセスやスレッドを使うべきなのはなんとなく分かるのだが、
これまで勉強してこなかったので、この際勉強して使えるようになろうと。

マルチスレッド(並行処理)とマルチプロセス(並列処理)の整理から

マルチプロセス

・実行中のプログラムのこと
・プロセス間でメモリの共有はない(プロセスごとに領域を確保)

メリット

・一つのプロセスでエラーが発生しても、ほかのプロセスには影響を及ぼさない。
・他のプロセスのことを考えなくてよいので、プログラミングミスが起きにくい

デメリット

・プロセス間でのデータ共有が困難
・生成に多くのオーバーヘッドを強いる

使いどころ

・処理を行う領域自体を分けて高速化したい

スレッド

・一つのプロセスの中に複数作成が出来る
・一つのプロセス内のスレッドはメモリ領域を共有する

メリット

・メモリの使用率が低い
・プロセスよりも少ない時間で生成できる

デメリット

・同時実行処理でデータ変更を行う場合には、排他ロック(GILなど)が必要
・一つのスレッドのクラッシュが全体に影響を及ぼす
・プログラミングミスが起きやすく、コーディングの難度が高い。

使いどころ

・レスポンスタイムを速くしたい
スループットを向上させたい

結局のところ、同一プロセス内で分岐させたいか、
そうでないかが争点になるのだろうか…

今回実装したい処理は、メイン関数の中でレスポンスと
サーバーでの内部処理を分岐させたいだけで、
プロセスを分ける必要はないので、スレッドを使って実装すればよい。

というわけでコードはこんな感じになった。

import threading

# メイン処理
def main(num):
    print('開始')
    # 新規スレッド生成
    p=threading.Thread(target=sub,args=(num,))
    # スレッド開始
    p.start()
    print('レスポンス')
    
# サブ処理
def sub(num):
    print('内部処理')
    for i in range(0,num):
        print(i)
    print('内部処理終了')
    
# メイン処理呼び出し
main(100)

実行結果

開始
内部処理
0
1
2
レスポンス
3
…
98
99
内部処理終了

因みにマルチプロセスだと以下になる。

# メイン
def main2(num):
    print('開始')
    # mainを明示(書かないとエラーになる)
    if __name__ == "__main__":
        # プロセス生成
        p=multiprocessing.Process(target=sub,args=(num,))
        # プロセス開始
        p.start()
    print('レスポンス')
    
# サブプロセス
def sub2(num):
    print('内部処理')
    for i in range(0,num):
        print(i)
    print('内部処理終了')
    
# メインプロセス呼び出し
main2(100)