演員模型

在電腦科學中，演員模型。演員模型在1973年於、Peter Bishop及Richard Steiger的論文中提出。它已經被用作併發計算的框架和併發系統的基礎。演員模型和其他類似工作的關係討論可見於。基本概念.演員模型推崇的哲學是“一切皆是演員”，這與面向物件程式設計的“一切皆是物件”類似。演員是一個運算實體，響應接收到的訊息，相互間是併發的：以上動作不含有順序執行的假設，因此可以並行進行。傳送者與已傳送通訊的解耦，是演員模型的根本優勢，演員模型啟用了非同步通訊並將控制結構當作訊息傳遞的模式。訊息接收者是透過地址區分的，有時也被稱作“郵件地址”。因此演員只能和它擁有地址的演員通訊。它可以透過接收到的資訊獲取地址，或者獲取它建立的演員的地址。演員模型的特徵是，演員內部或相互之間的計算本質上是併發性的，演員可以動態建立，演員地址包含在訊息中，互動只有透過直接的非同步訊息傳遞通訊，不限制訊息到達的順序。歷史.演員模型受到了Lisp、Simula、Smalltalk-72、和分組交換的影響。其發展“受到由幾十、幾百、甚至幾千個獨立微處理機構成的高度平行計算機器的前景所推動，其中的每個處理機都有自己區域性記憶體和通訊處理器，它們透過高效能網路進行通訊。”此後隨著採用多核和計算機架構的大規模併發計算的出現，人們已經重新燃起了對演員模型的興趣。在Hewitt、Bishop和Steiger的1973年刊物之後，在1975年博士論文中，為演員模型開發出了一種操作語義。和Hewitt在1977年發表了演員系統的公理法則。其他主要的里程碑包括：的1981年學位論文，它介入了基於的指稱語義；還有的1985年學位論文，它進一步發展出基於transition的語義模型，從而補充了Clinger的模型。這些工作促成了的全面發展。主要的軟體實現工作，由麻省理工學院的訊息傳遞語義小組完成，其成員包括Russ Atkinson、Giuseppe Attardi、Henry Baker、Gerry Barber、Peter Bishop、Peter de Jong、Ken Kahn、Henry Lieberman、Carl Manning、Tom Reinhardt、Richard Steiger和Dan Theriault。分別由加州理工學院的Chuck Seitz和麻省理工學院的Bill Dally領導的研究小組，致力於構造新的計算機架構，用以進一步發展演員模型中的訊息傳遞。有關工作詳見。演員模型的研究，已經開展於加州理工學院、京都大學、、MIT人工智慧實驗室、斯坦福國際研究所、斯坦福大學、伊利諾伊大學厄巴納-香檳分校、巴黎第六大學、比薩大學、東京大學研究室、荷蘭數學和計算機科學研究學會和其他一些地方。使用演員模型程式設計.一些程式語言使用了演員模型或變種。這些語言包括：早期的演員模型程式語言.後期的演員模型程式語言.演員模型庫及框架.演員模型庫及框架，允許使用者在沒有內建演員模型的語言中進行程式設計。這些框架包括：注意這裡沒有列出全部框架和庫。併發程式語言用例.儘管Erlang語言設計者並未如此表述，因其程序間通訊是透過訊息傳遞系統運作，它一般被引證為採用演員模型的典型代表之一。在Erlang中，所有程序都有一個自己的“郵箱”，它是從其他程序已經發送過來而仍未被消費的訊息的佇列。程序使用codice_1原語來檢索匹配預期模式的訊息。一個訊息處理例程針對每個模式依次測試這些訊息，直到其中有一個匹配。在訊息被消費並從郵箱中移除之時程序恢復執行。訊息可以包含任何Erlang結構，包括原始型別、元組、列表和函式。下面例子展示了Erlang對分散式程序的內建支援：% 建立一個程序並啟用函式web:start_server(Port, MaxConnections)ServerProcess = spawn(web, start_server, [Port, MaxConnections]),% 建立一個遠端程序並啟用函式% web:start_server(Port, MaxConnections)於機器RemoteNodeRemoteProcess = spawn(RemoteNode, web, start_server, [Port, MaxConnections]),% 傳送訊息到ServerProcess(非同步的)。訊息包含一個元組% 它具有原子"pause"和數"10"。ServerProcess ! {pause, 10},% 接收發給這個程序的訊息receivea_message -&gt; do_something;{data, DataContent} -&gt; handle(DataContent);{hello, Text} -&gt; io:format("Got hello message: ~s", [Text]);{goodbye, Text} -&gt; io:format("Got goodbye message: ~s", [Text])end.原型的演員程式語言.Hewitt在2006年發表了一個原型的演員程式語言，用意在於直接表達演員行為的重要方面。訊息採用如下表示法：程式語言的語義是透過將每個程式構造確定為有自己行為的演員來定義的。執行是透過在執行期間讓Eval訊息在程式構造之間傳遞來建模的。環境演員.每個Eval訊息都有一個充當環境的演員的地址，它能夠進行識別符號與值的繫結，也就是不變更的。上述環境演員建造在EmptyEnvironment演員之上，它在接收到Request[Lookup[identifier] customer]的時候，傳送給customer一個Thrown[NotFound[identifier]]。當它收到Bind請求的時候，EmptyEnvironment表現的如同上述環境演員。表示式.原型語言有如下種類的表示式，這裡的通訊包括Request[...]、Returned[...]和Thrown[...]，這裡的訊息包括Eval[...]、Bind[...]和Lookup[...]：在收到Request[Eval[environment] customer]的時候，傳送給environment一個Request[Lookup[] customer]。在收到Request[Eval[environment] customer]的時候，建立一個新演員evalCustomer1，傳送給一個Request[Eval[environment] evalCustomer1]，使得在evalCustomer1收到通訊Returned[theRecipient]的時候，建立一個新演員evalCustomer2，傳送給一個Request[Eval[environment] evalCustomer2]，使得在evalCustomer2收到通訊Returned[theCommunication]的時候，傳送給theRecipient一個theCommunication。在收到Request[Eval[environment] customer]的時候，建立一個新演員evalCustomer1，傳送一個Request[Eval[environment] evalCustomer1]，使得在evalCustomer1收到通訊Returned[theRecipient]的時候，建立一個新演員evalCustomer2，傳送給一個Request[Eval[environment] evalCustomer2]，使得在 evalCustomer2收到通訊Returned[theMessage]的時候，傳送給theRecipient一個Request[theMessage customer]。在收到Request[Eval[environment] customer]的時候，傳送給customer一個新演員theReceiver，使得在theReceiver收到通訊內容com的時候，建立一個新演員bindingCustomer，併發送給environment一個Request[Bind[i com] bindingCustomer]，而且#如果bindingCustomer收到Returned[environment’]，傳送給i一個Request[Eval[environment’]]#不然如果bindingCustomer收到Thrown[...]，嘗試i+1。在收到Request[Eval[environment] customer]的時候，傳送給customer一個新演員theReceiver，使得在theReceiver收到Request[message customer’]的時候，建立一個新演員bindingCustomer，併發送給environment一個Request[bind[i message] customer’]，而且# 如果bindingCustomer收到Returned[environment’]，傳送給i一個Request[Eval[environment’] customer’]# 不然如果bindingCustomer收到Thrown[...]，嘗試i+1。在收到Request[Eval[environment] customer]的時候，傳送給2一個Request[Eval[environment] customer]。在收到message[Eval[environment] customer]的時候，建立一個新演員evalCustomer，併發送給值一個Request[Eval[environment] evalCustomer]。在evalCustomer收到Returned[theValue]的時候，建立一個新演員bindingCustomer，併發送給environment一個Request[bind[ theValue] bindingCustomer]。在bindingCustomer收到Returned[environment’]的時候，傳送給體一個Request[Eval[environment’] customer]。在收到Request[Eval[environment] customer]的時候，傳送給customer一個Returned[theSerializer]，這裡的theSerializer是新演員，使得傳送到theSerializer的通訊按FIFO次序由行為演員處理，行為演員初始是.Eval[environment]，而且在theSerializer收到通訊內容com的時候，建立一個新演員customer’，傳送給行為演員一個Request[com customer’]，使得在customer’收到Returned[value]和Returned[theNextBehavior]的時候，Returned[value]被髮送給customer，而theNextBehavior被theSerializer用作下次通訊的行為演員。例子程式.下面是簡單的儲存單元格，它可以包含任何演員地址：Cell ≡"receiver"Request[Create[initial] customer]"send" customer Returned["serializer" ReadWrite(initial)]上述指令碼將建立一個儲存單元格，它採用的行為ReadWrite定義如下：ReadWrite(contents) ≡"behavior"Request[read[] customer]{"send" customer Returned[contents], Returned[ReadWrite(contents)]}Request[write[x] customer]{"send" customer Returned[], Returned[ReadWrite(x)]}例如，下列表達式建立一個單元格x，具有初始內容5，並接著併發的向它寫值7和9。"let" x = Cell.Create[5] "in" {x.write[7], x.write[9], x.read[]}上述表示式的值是5、7或9。影響.演員模型在併發計算的理論發展和實踐軟體開發中都有影響。理論.演員模型影響了π-演算和隨後的程序演算的發展。在Robin Milner的圖靈獎獲獎演說中，他寫到：純lambda演算現在只使用兩種東西來建造：項和變數。我們在程序演算上也能實現同樣的經濟性嗎？Carl Hewitt憑藉其演員模型，很久以前就應對了這個挑戰；他宣告了值、在值上的運算元和程序，都應該是同一種東西：即演員。這個目標打動了我，因為它蘊涵了表示式有著同質性和完整性 ... 但是很久以後我才明白瞭如何依據代數演算來達成這個目標 ...因此本著Hewitt的精神，我們的第一步，就是要求由項指示或由名字訪問的所有東西，包括值、暫存器、運算元、程序、物件，都是同一種東西；它們都應當是程序。實踐.演員模型在商業實踐中已經有了巨大的影響。例如，Twitter將演員用於可伸縮性應用。還有，Microsoft在其開發的非同步代理庫中使用了演員模型。