コンピュータサイエンスにおいて、アクターモデルとプロセス計算は、並行デジタル計算をモデル化するための密接に関連した2つのアプローチである。アクターモデルとプロセス計算の歴史を参照のこと。
両者のアプローチには多くの類似点がある一方で、いくつかの相違点もある(哲学的なものもあれば、技術的なものもある)。
アクターモデルとプロセス計算に関する出版物には、相互参照、謝辞、相互引用がかなり多く含まれています(アクターモデルとプロセス計算の歴史を参照)。
チャネルを用いた間接通信(例:ジル・カーンとデビッド・マックイーン[1977])は、並列計算および並行計算における通信において、意味論とパフォーマンスの両方に影響を与える重要な課題となっている。一部のプロセス計算は、直接通信ではなくチャネルを使用する点で、アクターモデルとは異なる。
同期チャネルには、チャネルにメッセージを送信する送信者は、受信者がチャネルからメッセージを取り出すまで、次の処理に進むことができないという特性があります。
put同期チャネルは、送受信を行うアクターによってモデル化できますget。以下は、単純な同期チャネルにおけるアクターの動作です。
put通信にはメッセージと、メッセージ受信時に確認応答が送信される宛先アドレスが含まれています。get 通信には、受信したメッセージが送信される宛先アドレスが存在する。get、アクターはFIFOput順で通信を選択し、指定されたアドレスにメッセージと確認応答を送信する。しかし、単純な同期チャネルでは、通信逐次プロセス(CSP) [Hoare 1978 および 1985]のようなプロセス計算には不十分です。これは、ガード付き選択コマンド (ダイクストラにちなんで) ( CSP では代替putコマンドと呼ばれる) を使用するためです。ガード付き選択コマンドでは、複数のチャネルで複数のオファー (ガードと呼ばれる) を同時にgetメッセージに対して行うことができますが、ガード付き選択コマンドの各実行で選択できるガードは最大で 1 つだけです。選択できるガードは 1 つだけなので、ガード付き選択コマンドは一般的に、一種の2 相コミット プロトコル、またはガードでタイムアウトが許容される場合(Occam 3 [1992] のように) には3 相コミット プロトコルさえも必要とします。
CSPで記述された以下のプログラムを考えてみましょう[Hoare 1978]。
[X :: Z!stop() || Y :: guard: boolean; guard := true; *[guard → Z!go(); Z?guard] || Z :: n: 整数; n:= 0; *[X?stop() → Y!false; print!n; [] Y?go() → n := n+1; Y!true] ]
XClinger [1981] によると、このプログラムはグローバルな非決定性を示している。なぜなら、非決定性は、3 つのプロセス、Y、 および の間の信号のタイミングの不完全な指定から生じるからであるZ。 の定義における繰り返しガード付きコマンドには、Z2 つの選択肢がある。
stopが から受け入れられたX場合、 にはY値falseが送信され、 にはprint値が送信されます。ngoが受け入れられるとY、nがインクリメントされ、Y値trueが送信されます。が からのメッセージZを受け入れると、 は終了します。 を受け入れると、 がfalseを送信し、 がガードの値として入力されると、 は終了します。 と の両方が終了すると、は入力を提供するアクティブなプロセスがなくなるため、終了します。stopXXstopYYXYZ
上記のプログラムでは、からX、ZからY、ZおよびZからへの同期チャネルがありますY。
Knabe [1992]によると、ChandyとMisra [1988]はこれを委員会調整問題に類似したものとして特徴づけた。
このセクションでは、同期プロセス計算におけるチャネルのためのシンプルな分散プロトコルを紹介します。このプロトコルにはいくつかの問題点があり、それらについては後述のセクションで説明します。
ガード付き選択コマンドの動作は以下のとおりです。
prepare。prepare to commit、他のすべての警備員にもメッセージを送信しますabort。 prepared to commit、ガードにcommitメッセージを送信します。ただし、ガードが実行できないという例外をスローした場合prepare to commit、ガード付き選択コマンドはプロセス全体を最初からやり直します。prepare、警備対象のコマンドは何も実行しない。警備員の行動は以下のとおりです。
prepare受信されると、ガードはprepare通信を申し出ている各チャネルにメッセージを送信します。ガードが通信できないブール値を持っている場合、prepareまたはチャネルのいずれかが通信できないと応答した場合、ガードは他のチャネルにメッセージをprepare送信し、通信できないと応答します。 abortprepareprepare to commit受信されると、ガードはprepare to commit各チャネルにメッセージを送信します。いずれかのチャネルが「できません」と応答した場合prepare to commit、ガードは他のチャネルにメッセージを送信しabort、その後「できません」という例外をスローしますprepare to commit。commit受信されると、ガードはcommit各チャネルにメッセージを送信します。abort受信されると、ガードはabort各チャネルにメッセージを送信します。チャネルの動作は以下のとおりです。
prepare to putの場合は準備完了と応答し、通信が受信されている場合は、できないという例外をスローします。prepare to getterminateprepare to putprepare to getの場合は準備完了と応答し、通信が受信されている場合は、できないという例外をスローします。 prepare to putterminateprepare to getprepare to commit to putの場合は準備完了と応答し、通信が受信されている場合は、できないという例外をスローします。prepare to commit to getterminateprepare to commit to putprepare to commit to getの場合は準備完了と応答し、通信が受信されている場合は、できないという例外をスローします。 prepare to commit to putterminateprepare to commit to getcommit put、以下のいずれかが受信されたかどうかに応じて、次の処理が行われます。 commit get通信を受信したら、まだ実行していない場合は、準備を実行し、クリーンアップしますput。getabort get、準備を中止してください。commit get、以下のいずれかが受信されたかどうかに応じて、次の処理が行われます。 commit put通信を受信したら、まだ実行していない場合は、準備を実行し、クリーンアップしますget。putabort put、準備を中止してください。abort put、準備を中止してください。abort get、準備を中止してください。ここでも、CSPで記述されたプログラム(上記「プロセス計算における同期チャネル」で説明済み)を考えてみましょう。
[X :: Z!stop() || Y :: guard: boolean; guard := true; *[guard → Z!go(); Z?guard] || Z :: n: 整数; n:= 0; *[X?stop() → Y!false; print!n; [] Y?go() → n := n+1; Y!true] ]
Knabe [1992] で指摘されているように、上記のプロトコル (単純な分散プロトコル)の問題点は、プロセスが (飢餓と呼ばれる現象)からのメッセージZを受け入れない可能性があり、その結果、上記のプログラムが何も出力しない可能性があることです。stopX
対照的に、アクターX、Y、Z、およびprintから構成される単純なアクターシステムを考えてみましょう。
"start"が受信された場合は、Zにメッセージ を送信する。"stop""start"が受信された場合は、Zにメッセージ を送信する。"go""go"nは、初期カウントが0である以下の動作で作成されます。 "start"が受信された場合は、何もする必要はありません。"stop"が受信された場合は、Yにメッセージfalseを送信し、メッセージをカウントして出力nします。"go"が受信された場合は、Yにメッセージtrueを送信し、受信した次のメッセージをカウントとして処理しnますn+1。アクター意味論の法則により、上記のアクターシステムは、アクターX、Y、Zそれぞれに"start"メッセージが送信され、結果として無限に大きくなる可能性のある数値が出力されると、必ず停止します。
CSPプログラムとアクターシステムの違いは、アクターZが複数のチャネルからガード付き選択コマンドを使用してメッセージを受け取るのではなく、到着順にメッセージを処理する点にある。アクターシステムの法則により、stopメッセージの到着は保証される。
CSPで記述された以下のプログラムを考えてみましょう[Hoare 1978]。
[Bidder1 :: b: bid; *[Bids1?b → process1!b; [] Bids2?b → process1!b;] || 入札者2 :: b: 入札; *[Bids1?b → process2!b; [] Bids2?b → process2!b;] ]
Knabe [1992] で指摘されているように、上記のプロトコル (単純な分散プロトコル)の問題点は、プロセスがまたはBidder2からの入札を決して受け入れない可能性があること (ライブロックと呼ばれる現象) であり、結果として には何も送信されない可能性があります。メッセージの受け入れを試みるたびに、 またはによって提示された入札がによって奪われるため、 は阻止されます。これは、 がおよびよりもはるかに高速にアクセスできることが判明したためです。したがって、が入札を受け入れ、処理し、 が入札を受け入れることを約束する前に別の入札を受け入れることができます。Bid1Bid2process2Bidder2Bids1Bids2Bidder1Bidder1Bidder2Bids1Bids2Bidder1Bidder2
Knabe [1992] で指摘されているように、上記のプロトコル (単純な分散プロトコル) の問題点は、同期チャネルを介してメッセージを送信するためのハンドシェイクを実行するために送信しなければならない通信の数が多いことです。実際、前のセクション ( Livelock ) で示したように、通信の数は無制限になる可能性があります。
上記の各節では、プロセス計算に同期チャネルを使用することに関連する以下の3つの問題点について説明しました。
上記すべてにおいて、複数のチャネルからメッセージを取得するためにガード付き選択コマンドを使用することから問題が生じていることは注目に値する。
非同期チャネルには、チャネルにメッセージを送信する送信者が、受信者がチャネルからメッセージを取り出すのを待つ必要がないという特性があります。
put非同期チャネルは、送受信を行うアクターによってモデル化できますget。以下は、単純な非同期チャネルにおけるアクターの動作です。
put通信にはメッセージと、受信確認が即座に送信される宛先アドレスが含まれています(get通信がメッセージを受信するのを待つことなく)。get 通信には、受信したメッセージが送信される宛先アドレスが存在する。Join-calculusプログラミング言語(1996年発表)は、ローカルおよび分散並行計算を実装しました。非同期チャネルと、プロシージャ呼び出しに使用される一種の同期チャネルを組み込んでいます。AghaのAπアクター計算(AghaとThati 2004 )は、非同期π計算の型付きバージョンに基づいています。
代数的手法の使用はプロセス計算において先駆的に行われた。その後、アクターシステムに関する代数的推論を提供することを目的としたいくつかの異なるプロセス計算が(Gaspari and Zavattaro 1997 )、(Gaspari and Zavattaro 1999 )、(Agha and Thati 2004 )で開発された。
ウィル・クリンガーは(アイリーン・グライフ[1975]、ゴードン・プロトキン[1976]、ヘンリー・ベイカー[1978]、マイケル・スミス[1978]、フランセズ、ホア、レーマン、デ・ローバー[1979]の研究に基づいて)、 1981年の博士論文でドメイン理論を用いてアクターモデルの最初の満足のいく数学的表示理論を発表した。彼の意味論は、アクターモデルの無制限の非決定性を、 CSP [ホア 1978]および並行プロセス[ミルンとミルナー 1979]の制限された非決定性と対比させた(表示意味論を参照)。ロスコー[2005]は、ホア[1985]のCommunicating Sequential Processesのその後のバージョンに対して、無制限の非決定性を持つ表示意味論を開発した。さらに最近では、カール・ヒューイット[2006b]が時間図に基づいてアクターの表示的意味論を開発した。
ウーゴ・モンタナリとキャロリン・タルコット[1998]は、アクターとプロセス計算を調和させようとする試みに貢献した。