マルチプロセス、マルチスレッドを使うとき
マルチプロセスとか、マルチスレッドは難易度が高いです。
以下のように、非同期処理、多重処理、定期処理で使用します。
非同期処理
処理Aと処理Bがあって、二つの処理を別々に処理したいとき非同期処理を用います。
例えば、Webサーバでデータを渡したらすぐにOKを返したいときなどに使用します。
多重処理
同じ処理を同時に行う多重処理です。
同じ処理を複数実行して性能を高めるために使用します。
定期処理
1日に1回とか、10分に1回やりたい処理があるとき、定期処理を用います。
マルチプロセスとマルチスレッドのできることは変わりませんが、以下のように基本的にはマルチスレッドを使いましょう。
基本的にはマルチスレッドで
マルチプロセスの方はUnix草創期から存在するのに対してマルチスレッドが実装できるようになったの2000年代、普及したのは2010年代頃です。
マルチプロセスとマルチスレッドの比較表です。
メリット | デメリット | |
マルチプロセス | 古いシステムなどどんなシステムでも使える | 実装難易度高い リソースの後始末の難易度高 リソース使用量多い |
マルチスレッド | 実装難易度低い リソースの後始末は容易 リソース使用量少ない | 古いシステムでは使用できない |
この表を見ると誰もがマルチスレッドを選ぶと思います。非同期処理、多重処理、定期処理を行う必要が出てきた時、基本的にはマルチスレッドを選択すればよいです。
マルチスレッドのない古いOSでマルチプロセスのプロフェッショナルになったような人以外は、普通はマルチスレッドを選びましょう。
筆者は、プロジェクトの再利用できるものがマルチプロセスで作ってあってそれ使えとか言われることがありました。そういう変な境遇でない限りはマルチスレッドをで行きましょう。
もう一度言います。
基本的にはマルチスレッド
です。
マルチプロセスを選ばなければならないとき
とは言ってもマルチプロセスを選ばなければならないときがあります。以下の2パターンではマルチプロセスとするのが自然です。
- 別サーバへ独立させる道がある
- 外部プログラムが別プロセス
別サーバへ独立させる道がある
将来的に該当する処理を別サーバにする気がある場合はマルチプロセスでないといけません。
通信もhttpやsocketにするなどして、別サーバに分離されても通信できるものにします。
通信をhttpにできるのなら、マルチプロセスであっても難しいところはありません。(httpを実装するのが面倒ですが)
外部プログラムが別プロセス
よくあるのはWebサーバ(apacheやnginx)で外からデータを受け取る場合です。
Webサーバ側では、データベースにデータを入れて終わり、などきっちりとルールを決めて対応しましょう。
面倒なのは情報の受け渡し
マルチプロセス、マルチスレッドで面倒なのは情報の受け渡し方です。
データベースが得意な人はデータベースを情報の受け渡しに使ってください。排他とかデータ設計はデータベースのセンスと論理で組み立てるのが一番よいです。
難しいのはデータベースを知らない人です。データベースを使っている人からするとデータベースなしの世界は信じられないと思いますが、データベースなしの世界で成長したエンジニアは少なからず存在します。
重要なのはデータの隠蔽
データベースは各プロセス、各スレッドから自由に見えるので、データベースの人から見ると「データを隠蔽する」という考え方は変に思えます。データベースの人は息を吸う如くにデータ設計、CRUD設計を行うので問題ないです。しかし、データベースを使ったことない人は、データを他モジュールに公開してはなりません。
時々、共有メモリ(やグローバルメモリ)を各プロセス(や各スレッド)から、自由に見えるようにして自由に読み書きしてね、というアーキテクチャを作る人がいますが、そういうのはやめましょう。
あるデータを管理するモジュールをしっかりと決め、そのデータへのアクセスはそのモジュールのインタフェースを通すというような形が、望ましいです。
データを隠蔽するということによって、モジュールの結合度が疎になりますし、データドリブン的な設計なので趣味がよい設計になりますよ。
マルチスレッド
マルチスレッドはメモリ空間を共有できます。しかしグローバル変数を二つのモジュールでいじったりするのはやめましょう。
「データを頂戴」「データを加工してね」というようなインタフェースではなく、「データをあげるから後はよろしく」というようなインタフェースにするなど工夫していきましょう。腕の見せ所です。
非同期、多重を常に意識して、mutexによる排他を行います。
マルチプロセス プロセス間通信
プロセス間通信は、以下のようなものがあります。
- 共有メモリ
- シグナル
- パイプ
- メッセージキュー
- セマフォ
- ソケット
- http RESTful
上記の中で使ってよいのは「ソケット」と「http」だけです。それ以外は経験あるなら使っていいと思いますが、普通は使いこなせません。やめておいた方がよいです。
なぜお薦めしないかというと、扱いがとても難しいのです。共有メモリは作ったら破壊することを考えないといけません。起動時、共有メモリを作ろうとしたらすでにあるときはどうすればよいか、とか考えないといけないことが多すぎるのです。
ときどき、ファイルでプロセス間通信をやっている人がいます。ちょっといいハックをしたと思っているかもしれませんが、ファイルを通信に使うのは百害あって一利なしです。ファイル残存時のことを考える必要がありますし、openした後にしかロックできないのでどうしても隙間があります。ファイル名を考えたりしなければならないので、やめましょう。
データベースエンジニアはデータベースを通信用に使っていいです。
それ以外の方はプロセス間通信はソケットで独自プロトコルを作るかhttpにしましょう。socketやhttpはプログラムで書くのは結構技術がいります。その技術力がないならプロセス間通信をやるのはやめた方がよいです。
まとめ
マルチプロセスとマルチスレッドについて説明しました。
基本的にはマルチスレッドで非同期処理、多重処理、定期処理を行います。
コメント