メッセージ (コンピュータ)
計算機科学におけるメッセージ (message) とは、情報の伝達を目的とする、順序付けられた文字列である。JISでは、情報理論および通信理論におけるmessageの訳語として通報という用語が割り当てられているコンピュータと人間との対話のため、単に画面等へ表示される文字列を指す場合は、通信文または通知と訳されることもある。エラーメッセージ (error message) は「誤り通知」となる。。
メッセージパッシング (message passing) とは、並行計算・並列計算、オブジェクト指向、プロセス間通信で使われる通信方式である。プロセスもしくはオブジェクトといったモデルではメッセージ(ゼロ以上のバイト、複雑なデータ構造、プログラムコードも含む)を送ったり受けたりできる。メッセージを待つことによって同期することもできる。メッセージパッシングに基づく主なモデルとしてアクターモデルやプロセス代数がある。
メッセージパッシングは、ひとつもしくは多くの受信者 (receiver) に対して送信者 (sender) がデータを配送できる通信方法である。通報の形として遠隔メソッド呼び出し(remote method invocation; RMI)、シグナル、データパケットなどがある。メッセージパッシング機構を設計するとき、下記のような方針から設計方針を選択する。
メッセージのやりとりは一対一、一対多(マルチキャストもしくはブロードキャスト)、多対一(クライアントサーバモデル)か
重要な理論上の基礎であるアクターモデル、プロセス計算といった並行計算はメッセージパッシングを基礎としている。メッセージパッシングを使った並行システムは、言語内の機能としてメッセージパッシングする場合と言語からの一連のライブラリ呼び出しで実現する場合がある。
前者の例は多くの分散オブジェクトシステムが含まれる。後者の例としては、カーネルとサーバブロック間でメッセージをやりとりするマイクロカーネルオペレーティングシステムや、高性能計算における Message Passing Interface がある。メッセージパッシングの概念は、グラフモデル上のベイズ推定などでも使われている。
Microsoft Windowsなどのオペレーティングシステムにおいて、メッセージとは、オペレーティングシステム上で動くアプリケーションに対して、オペレーティングシステムが管理しているデバイスあるいは別のプロセスやスレッドからの入力を伝えるために送られる、ひとかたまりのデータ集合のことである。メッセージを送受信することを通知とも呼ぶ。
オペレーティングシステムはメッセージをメッセージキューに保管し、アプリケーションはメッセージキューに保管されていたメッセージを受け取り、それを元に処理を行う。例えば「画面座標 (10, 20) の位置をマウスで左クリック」という情報をオペレーティングシステムが感知した場合、オペレーティングシステムはその情報をメッセージキューに保管する。アプリケーションはそのメッセージを受け取って対応した処理を行う。
アプリケーションは常にオペレーティングシステムからのメッセージを待機するようなイベント駆動方式のプログラムになっており、この一連のプログラムの機構をメッセージループという。メッセージキューを定期的に監視・確認するポーリング方式でメッセージループが実装されることもある。
分散オブジェクトや ONC RPC、CORBA、Java RMI、DCOM、SOAP、.NET Remoting、WCF、CTOS、QNX Neutrino RTOS、OpenBinder、D-Bus のような遠隔メソッド呼び出しあるいはそれに類するものはメッセージパッシングシステムである。メッセージパッシングシステムは共有のないシステムと呼ばれている。なぜならば、メッセージパッシング型のシステムは、メッセージという抽象化によってその下位に存在する状態変化や実装などを隠蔽するものだからである。
メッセージパッシングモデルはデータを端末(アクター、プロセス、スレッドなど)に送信するような通達方式で、プログラミング言語で典型的に定義されている。そのようなメッセージングはSOAPによってWebサービスの中で使われている。この考え方はパケットより大きく、任意に信頼性や耐久性や安全性やトランザクションを追加したものを除く高いレベルのメッセージデータグラムである。メッセージもまた一般的に同じ向きのプロセス間通信に使われる。また別の一般的に使われる技術はストリームもしくはパイプで、そのようなデータは初歩的なデータアイテムの一連として送信される(仮想回線の高等レベルでは)。
同期メッセージパッシングシステムでは送信者と受信者がお互いにメッセージの転送を待つ。つまり、送信者は受信者がメッセージを受信するまでプログラムを再開できない。
同期通信は二つの利点がある。利点の一つ目はメッセージ転送において送信者と受信者で同期をとるため、プログラムを単純化できることである。利点の二つ目はバッファを必要としないことである。メッセージはいつでも受信側に保存される。なぜならば、送信者は受信者の準備が完了するまで送信を待つためである。
非同期メッセージパッシングシステムは受信者から送信者に準備ができる時間を待たずにメッセージを送る。非同期通信の利点はお互いに待つことがないので、お互いの計算処理をオーバーラップして行える。
同期通信は送信者がいつも受信者が続ける前にメッセージを応答したことを確実にする非同期通信をベースに築かれている。
非同期通信はバッファを必要とするが、そのバッファが満杯になると問題の原因になる。送信者をブロックするか今後のメッセージを切り捨てるか判断をしなければならない。送信者をブロックすれば、予期しないデッドロックを引き起こすかもしれない。メッセージを捨てた場合通信の信頼性は無くなる。
メッセージパッシングはプログラム間で情報を受け渡すためのもうひとつの通信方法、つまりCallと対比されるべきである。伝統的なCallにおいては、引数は典型的には一つ以上の汎用レジスタまたは引数のアドレスを内包しているパラメータリストを通じて、"callee" すなわち「呼び出し先」(receiver: 受信者)に渡される。この通信形式はメッセージパッシングと比較して少なくとも三つの大きな違いがある。
メッセージパッシングではどの引数も、新しいメッセージの中にコピーするのに十分なメモリを余計に必要とする。これはオリジナルの引数のサイズの大小によらない。したがって、もし引数のうちのひとつがwebページを記述する10,000オクテットのHTML文字列だとすると、受信プログラム(ローカルプログラムでないならば)に完全にコピーされなければならない(そしてさらに送信されなければならないだろう)。
対照的に、callの手法ならば、それぞれの引数に対して4から8バイト分のアドレスしか必要としない。さらに汎用レジスタならば追加の記憶領域はゼロであり、送信時間もゼロである。これはもちろん分散システムでは不可能である。というのも、呼び出し元 (caller) のアドレス空間における(絶対)アドレスは、リモートプログラムでは通常意味をなさないからである。ただし、もしcalleeが前もってcallerのメモリの正確な(少なくとも一部の)コピーを有していたならば、相対アドレスが利用できるかもしれない。
オブジェクト指向の幾つかの専門用語の中にメッセージはオブジェクトにコントロールを渡すという意味で使われる。もしオブジェクトがそのメッセージに応答したならばそれはそのメッセージに対するメソッドを持っている。詳しくはオブジェクト指向プログラミングを参照すること。
純粋なオブジェクト指向ではメッセージパッシングは排他的にダイナミックディスパッチに投げられる様に機能する。
同じメッセージを二回同じオブジェクトに送信した場合、普通そのメソッドを二回請求する結果となる。もし、名前と引数が同じならば二つのメッセージは同じメッセージタイプと考えられている。
オブジェクトは自分のメソッド本体から他のオブジェクトにメッセージを送信できる。メッセージパッシングシステムの中で、究極遅延束縛 (extreme late binding) が可能である。
アラン・ケイ は彼の視点のオブジェクト指向プログラミングの中ではオブジェクトよりも重要なコンセプトだが、人々はよくそのポイントと場所を見逃し、オブジェクト自体に重点をおきすぎ、十分メッセージをその間に送ってないと主張した。ライブ分散オブジェクトのプログラミングモデルはこの所見を踏まえて作られた。それは分散型データフローのコンセプトを使い複雑な分散型システムの振る舞いをメッセージパターンの(高レベル)機能スタイル仕様書とみなした。
幾つかの言語では、あるオブジェクトがメッセージを処理するメソッドを持っていなくとも、それを持っているであろう他のオブジェクトを知っている場合に、メソッド呼び出しを1つのオブジェクトから他のオブジェクトに転送、もしく委譲することをサポートしている。メッセージ転送を参照。
1977年、カール・ヒューイットは、計算制御構造は「メッセージパッシングのパターン」と見ることができると主張した。
Smalltalk及びSelfやObjective-CなどSmalltalk系統のオブジェクト指向言語においてメッセージは、メソッドを起動するセレクターと引数の組み合わせ、およびセレクターと引数を合わせたオブジェクトを示す。
例えば上記の式であれば、+ 1とselectorとselector: 0 and: 2が前者のメッセージとなる。C++系統の言語におけるメンバー関数の呼び出しに類似しているが、Smalltalk系統の言語はメンバー関数の実装部分にあたるメソッドとメッセージは独立した存在であり、メッセージはクラスに紐づかない。また、必ずしもセレクターとメソッドは一対一ではなく一つのメソッドに複数のセレクターを取り付けることができ、セレクターが異なるメッセージを同じメソッドで処理することができる例えばSmalltalkであれば#addSelector:withMethod:で追加できる。。また、メッセージと対応したメソッドが一切存在しないオブジェクトでもメッセージを受信することが可能になっている例えばSmalltalkであればメソッドが存在しないメッセージを#doesNotUnderstand:で受信することができる。メッセージ転送を参照。。