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言語で学ぶ並行プログラミングによると、コードの簡潔さと疎結合を重視するならメッセージパッシングが向いている。