スポンサーリンク

【Python】並行処理と並列処理、threadingでの実装

スポンサーリンク
スポンサーリンク
この記事は約4分で読めます。

並行処理と並列処理に関するメモ

 

プロセス、スレッド、タスクについて

タスクはスレッドによって処理される。

スレッドはプロセスの中に最低1つある。

プロセスはOSが管理・実行する。

このことを前提に、プロセスとスレッドの関係についてメモする。

 

あるアプリケーションを起動したとき、OSにとってはプロセスが1つ起動している。

あるアプリケーションは複数の処理を行うことができるので、1個のプロセスには複数のスレッドが動いている。

1つのプロセスには最低でも1つのスレッドがある。

 

Pythonで複数のタスクを同時に処理するには、以下の2通りの方法がある。

・複数のプロセスを立ち上げ、それぞれ1つずつスレッドを立ち上げる

・1つのプロセスの中で複数のスレッドを立ち上げる

複数のプロセスで複数のスレッドを立ち上げることもできるが複雑になる。

 

 

並行処理と並列処理の違い

 

並行処理

1つのプロセッサで複数のスレッドを立ち上げてタスクを処理する。

ある時点では1つのスレッドの処理しか行っていないが、複数のスレッドを高速に切り替えながら行う。

そのため複数のスレッドの処理を同時に行っているように見える。

 

並行処理では1つのプロセッサ(CPUコア)に割り当てられたリソース(メモリなど)を複数のスレッドが共有している。

そのため、あるスレッドでのタスクの処理によって、別スレッドのタスクで保持していた情報などが意図せず書き換えられる可能性がある。

並行処理ではこの点を意識しておく必要がある。

 

 

並列処理

複数のプロセッサで、それぞれ最低1つのスレッドを立ち上げてタスクを処理する。

マルチコア(プロセッサを複数持つ)のコンピュータでしか行うことができないが、ある時点で複数の処理を同時に行っている。

 

それぞれのプロセッサ(CPUコア)に対して最低1つ以上のスレッドを作成してタスクを行う。

並行処理とは違って一定時間で別のスレッドに切りかえるわけではなく、完全に同時に別々のタスクを処理している。

複数のプロセッサそれぞれに複数のスレッドを作成して、並行処理を並列処理するようなこともできると思われるが複雑になりすぎる。

 

 

threadingでの並行処理の実装

 

逐次処理

まずは逐次処理。並行処理・並列処理のどちらも使わず、上から順番に処理を行う。

task1とtask2を順番に処理する。

実行すると、task1を5秒程かけて処理する。

次にtask2を2秒程かけて処理する。

合計は7秒程の処理時間になる。

 

 

並行処理1

次に並行処理。1つのプロセスで複数のスレッドを立ち上げて複数のタスクを処理する。

以下はthreadingを使った並行処理。

処理の流れは以下の通り。

task1とtask2の順に処理を開始。

task1は5秒程、task2は2秒程の処理なのでtask2の方が先に終わる。

task2が先に終わっているので、プログラム全体の終了はtask1の終了時間次第になる。

task1が5秒程かけて処理を終えるので、プログラム全体も5秒ほどで処理を終える。

 

threadingは組み込みモジュール。

threadingからThreadをインポートし、Threadをインスタンス化して使用している。

thread1,thread2はThreadのインスタンス。2つのスレッドを作成し、thread1,thread2という名前を付けた。

スレッドはstartメソッドで実行開始し、joinメソッドで終了を待機する。

joinメソッドは、joinメソッドを使用したスレッドが終了するまで次の処理に進むことを待機させることができる。複数のスレッドで足並みをそろえたいときに使用する。

今回の例ではthread2の方が早く終わるので、thread1の終了を待つためにthread1にjoinメソッドを付けている。

thread1のjoinメソッドをコメントアウトすると、thread2が終了したらthread1の終了を待たずに次の処理へ進んでしまう。

逆にthread2のjoinメソッドをコメントアウトしても、thread2の方が速く終わり、後からthread1が終了するのであまり意味はない。

次の処理に進む際、全てのスレッドが終わるまで待機させたい場合は、処理の終了が遅い方に対してjoinメソッドを使用する。

 

 

並行処理2

良い例ではないかもしれないがもう一例

1つのプロセスで3つのスレッドを作り3つのタスクを並行処理し、最後に4つ目のスレッドを立てて4つ目のタスクを処理している。

 

 

参考

threading — スレッドベースの並列処理 — Python 3.12.0 ドキュメント

コメント