TL;DR

プロセスやスレッド、オブジェクトなどが、メモリを共有せずにメッセージを送り合って通信する方式。並行処理のモデルや、オブジェクト指向プログラミングの基礎になっている。

なぜ必要か

Wikipedia によると、メッセージパッシングを使うと、構成要素がメモリを共有せずに情報をやり取りできる。Go の公式ブログは「メモリを共有して通信するのではなく、通信によってメモリを共有せよ」と述べている。チャネルでデータを渡すと、そのデータにアクセスできるゴルーチンは常に 1 つになるので、ロックで共有データを守る必要がない。

仕組み

Wikipedia によると、メッセージパッシングには同期と非同期の 2 種類がある。同期では、送信側は受信側がメッセージを受け取るまで待つ。非同期では、メッセージはキューやバッファに入り、送信側はそのまま処理を続ける。

理論的なモデルとしては、アクターモデルやπ計算がある。CSP でも、プロセスが値のコピーを受け渡して通信する。

例

Go のチャネル、MPI、マイクロカーネルの OS、CORBA や Java RMI のような分散オブジェクトがある。

注意点

Wikipedia によると、非同期のメッセージパッシングでは、バッファが満杯になったとき、送信側をブロックしてデッドロックの危険を負うか、メッセージを捨てて信頼性を下げるかを選ぶ必要がある。

100 Go Mistakes and How to Avoid Them は、Go のブロッキングバグの多くがチャネルを介したメッセージパッシングの誤った使い方から生じている、という研究を紹介している。Go言語で学ぶ並行プログラミングによると、コードの簡潔さと疎結合を重視するならメッセージパッシングが向いている。

関連

出典