メッセージパッシングとは
計算機科学における「メッセージ」とは、情報の伝達を目的とする、順序付けられた文字列のことです。JIS規格では、情報理論および通信理論における「message」の訳語として「通報」という用語が用いられています。
メッセージパッシングは、
並行計算、
並列計算、
オブジェクト指向、
プロセス間通信などで用いられる通信方式です。
プロセスや
オブジェクトは、メッセージ(ゼロ以上のバイト、複雑なデータ構造、プログラムコードなどを含む)を送受信することで、相互に通信や同期を行います。
メッセージパッシングの基本モデルには、
アクターモデルや
プロセス代数があります。
メッセージパッシングの概要
メッセージパッシングは、送信者から受信者へデータを配送する通信方法です。メッセージの形式としては、遠隔メソッド呼び出し(RMI)、シグナル、データパケットなどがあります。
メッセージパッシング機構の設計においては、以下の点が考慮されます。
個々のメッセージの送受信を確実に行うかどうか
メッセージが送信された順序通りに受信されることを保証するかどうか
メッセージのやり取りは一対一、一対多(
マルチキャスト/
ブロードキャスト)、多対一(
クライアントサーバモデル)のいずれか
通信の同期が必要かどうか
メッセージパッシングは、
アクターモデルや
プロセス計算といった
並行計算の基礎となる重要な概念です。実装方法としては、言語内の機能として提供される場合と、ライブラリ呼び出しとして提供される場合があります。
前者の例としては分散
オブジェクトシステムが挙げられ、後者の例としては、マイクロカーネル
オペレーティングシステムや、
高性能計算で用いられる
Message Passing Interface (MPI) が挙げられます。メッセージパッシングの概念は、
ベイズ推定などの分野でも応用されています。
オペレーティングシステム(OS)においては、メッセージは、OS上で動作するアプリケーションに対して、OSが管理する
デバイスや他の
プロセス/スレッドからの
入力を伝えるために送られるデータ集合のことです。メッセージの送受信は「通知」とも呼ばれます。
OSはメッセージを
メッセージキューに保管し、アプリケーションは
メッセージキューからメッセージを受け取り、それに基づいて処理を行います。
例えば、OSが「画面座標 (10, 20) の位置をマウスで左クリック」という情報を検知した場合、その情報を
メッセージキューに格納します。アプリケーションはメッセージを受け取り、対応する処理を実行します。
アプリケーションはOSからのメッセージを常に待機するイベント駆動型のプログラムとして実装され、この一連の処理機構を「メッセージループ」と呼びます。メッセージループは、
メッセージキューを定期的に監視するポーリング方式で実装されることもあります。
メッセージパッシングシステムとモデル
分散
オブジェクト、ONC RPC、CORBA、Java RMI、DCOM、SOAP、
.NET Remoting、WCF、CTOS、
QNX Neutrino RTOS、OpenBinder、
D-Bus などは、遠隔メソッド呼び出しやそれに類するメッセージパッシングシステムです。
メッセージパッシングシステムは、「共有なしシステム」とも呼ばれます。これは、メッセージパッシング型のシステムが、メッセージという抽象化によって、下位レイヤーにおける状態変化や実装を隠蔽するためです。
メッセージパッシングモデルは、データを端末(アクター、
プロセス、スレッドなど)に送信する通信方式であり、プログラミング言語で定義されることが一般的です。このメッセージングは、SOAPを用いて
Webサービスで利用されます。メッセージはパケットよりも大きく、信頼性、耐久性、安全性、
トランザクションなどの機能が追加されることがあります。
メッセージは一般に
プロセス間通信で使用されますが、ストリームやパイプといった技術も同様に利用されます。ストリームやパイプでは、データは初歩的なデータアイテムの連続として送信されます。
同期通信と非同期通信
メッセージパッシングには、同期通信と非同期通信という2つの方式があります。
同期メッセージパッシング:送信者と受信者がメッセージの送受信を互いに待機します。送信者は、受信者がメッセージを受信するまで処理を再開できません。
利点:プログラムが単純化され、バッファが不要
非同期メッセージパッシング:受信者の準備を待たずにメッセージを送信します。送信者は、メッセージを送信後、すぐに次の処理を開始できます。
利点:送信者と受信者が並行して処理を進めることが可能
同期通信は、非同期通信を基盤として実装されることもあります。非同期通信では、バッファが必要になりますが、バッファが満杯になると、送信者をブロックするかメッセージを破棄する必要があります。ブロックするとデッドロックが発生する可能性があり、メッセージを破棄すると通信の信頼性が損なわれます。
メッセージパッシングと関数呼び出しの比較
メッセージパッシングは、プログラム間で情報を交換するための別の通信方法、すなわち関数呼び出しと比較されるべきです。従来の関数呼び出しでは、引数はレジスタやパラメータリストを通じて「呼び出し先」に渡されます。メッセージパッシングと関数呼び出しの間には、少なくとも3つの大きな違いがあります。
1.
合計メモリ使用量:メッセージパッシングでは、引数は新しいメッセージにコピーされるため、余分なメモリが必要になります。引数が大きいほど、コピーに必要なメモリも大きくなります。一方、関数呼び出しでは、引数のアドレスのみが渡されるため、メモリ使用量が少なくなります。
2.
通信速度:関数呼び出しは、レジスタやアドレス渡しによって高速に引数を渡すことができます。一方、メッセージパッシングでは、データのコピーや送信が必要になるため、通信速度が遅くなる傾向があります。
3.
ローカリティ:関数呼び出しは、同じアドレス空間内での通信を想定しています。一方、メッセージパッシングは、異なるアドレス空間やネットワークを介した通信にも利用できます。
メッセージパッシングスタイルの例
メッセージパッシングは、さまざまなプログラミングモデルやシステムで利用されています。
アクターモデルの実装
アモルファスコンピューティング
アンチ
オブジェクト
フローベースプログラミング
SOAP
Smalltalk
他のプログラミングモデルへの影響
オブジェクト指向プログラミングにおいて、「メッセージ」は
オブジェクトに処理を要求する意味で使用されます。
オブジェクトがメッセージに応答する場合、それはメッセージに対応するメソッドを持つことを意味します。純粋な
オブジェクト指向では、メッセージパッシングは動的ディスパッチに結び付けられます。
メッセージを同じ
オブジェクトに2回送信した場合、通常、対応するメソッドが2回実行されます。メッセージの名前と引数が同じであれば、それは同じメッセージタイプと見なされます。
オブジェクトは、自身のメソッド本体から他の
オブジェクトにメッセージを送信できます。メッセージパッシングシステムでは、究極の遅延束縛が可能です。
アラン・ケイは、
オブジェクト指向プログラミングにおいて、
オブジェクトよりもメッセージが重要であると主張しました。
一部の言語では、
オブジェクトがメソッドを持たない場合、他の
オブジェクトにメソッド呼び出しを転送する(または
委譲する)機能をサポートしています。メッセージ転送を参照してください。
1977年、カール・ヒューイットは、計算制御構造は「メッセージパッシングのパターン」として捉えることができると提唱しました。
Smalltalk系統の言語におけるメッセージ
SmalltalkやSelf、
Objective-CなどのSmalltalk系統の
オブジェクト指向言語では、メッセージはメソッドを起動するセレクターと引数の組み合わせ、およびそれらを合わせた
オブジェクトを指します。
Smalltalkでは、`1 + 2`という式は、`+ 2`というメッセージを1という
オブジェクトに送ることを意味します。C++系統の言語におけるメンバー関数の呼び出しに似ていますが、Smalltalkではメッセージとメソッドは独立した存在であり、メッセージはクラスに紐づきません。
また、セレクターとメソッドは必ずしも一対一ではなく、複数のセレクターを同じメソッドに関連付けることができます。これにより、異なるメッセージに対して同じ処理を実行できます。さらに、メッセージに対応するメソッドを持たない
オブジェクトでもメッセージを受信できます。