演员模型

電腦科學中,演員模型英語:)是一種並行運算上的模型。「演員」是一種程式上的抽象概念,被視為並行運算的基本單元:當一個演員接收到一則訊息,它可以做出一些決策、建立更多的演員、傳送更多的訊息、決定要如何回答接下來的訊息。演员可以修改它们自己的私有状态,但是只能通过消息间接的相互影响(避免了基于锁的同步)。

演員模型在1973年於Carl Hewitt、Peter Bishop及Richard Steiger的論文中提出[1]。它已经被用作并发计算理论理解框架和并发系统实际实现基础。演员模型和其他类似工作的关系讨论可见于演员模型和进程演算

基本概念

演员模型推崇的哲学是“一切皆是演员”,这与面向对象编程的“一切皆是对象”类似。

演员是一个运算实体,响应接收到的消息,相互间是并发的:

  • 发送有限数量的消息给其他演员;
  • 创建有限数量的新演员;
  • 指定接收到下一个消息时要用到的行为。

以上动作不含有顺序执行的假设,因此可以并行进行。

发送者与已发送通信的解耦,是演员模型的根本优势,演员模型启用了异步通信并将控制结构当作消息传递的模式[2]

消息接收者是通过地址区分的,有时也被称作“邮件地址”。因此演员只能和它拥有地址的演员通信。它可以通过接收到的信息获取地址,或者获取它创建的演员的地址。

演员模型的特征是,演员内部或相互之间的计算本质上是并发性的,演员可以动态创建,演员地址包含在消息中,交互只有通过直接的异步消息传递通信,不限制消息到达的顺序。

历史

演员模型受到了LispSimulaSmalltalk-72基于权限的系统分组交换的影响。其发展“受到由几十、几百、甚至几千个独立微处理机构成的高度并行计算机器的前景所推动,其中的每个处理机都有自己局部内存和通信处理器,它们通过高性能网络进行通信。”[3]此后随着采用多核众核计算机架构的大规模并发计算的出现,人们已经重新燃起了对演员模型的兴趣。

在Hewitt、Bishop和Steiger的1973年刊物之后,Irene Greif在1975年博士论文中,为演员模型开发出了一种操作语义[4]Henry Baker和Hewitt在1977年发表了演员系统的公理法则[5][6]。其他主要的里程碑包括:William Clinger的1981年学位论文,它介入了基于幂域指称语义[3];还有Gul Agha的1985年学位论文,它进一步发展出基于transition的语义模型,从而补充了Clinger的模型[7]。这些工作促成了演员模型理论的全面发展。

主要的软件实现工作,由麻省理工学院消息传递语义小组完成,其成员包括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人工智能实验室斯坦福国际研究所斯坦福大学伊利诺伊大学厄巴纳-香槟分校[8]巴黎第六大学比萨大学东京大学米澤研究室、荷兰数学和计算机科学研究学会和其他一些地方。

使用演员模型编程

一些编程语言使用了演员模型或变种。这些语言包括:

早期的演员模型编程语言

后期的演员模型编程语言

演员模型库及框架

演员模型库及框架,允许用户在没有内置演员模型的语言中进行编程。这些框架包括:

名称 状态 最新发行 许可证 语言
ReActed[26] 活跃 2022-11-30 Apache 2.0 Java
Acteur[27] 活跃 2020-04-16[28] Apache-2.0 / MIT Rust
Bastion[29] 活跃 2020-08-12[30] Apache-2.0 / MIT Rust
Actix[31] 活跃 2019-05-30[32] MIT Rust
Aojet[33] 活跃 2016-10-17 MIT Swift
Actor[34] 活跃 2017-03-09 MIT Java
Actor4j[35] 活跃 2020-01-31 Apache 2.0 Java
Actr[36] 活跃 2019-04-09[37] Apache 2.0 Java
Vert.x[38] 活跃 2018-02-13 Apache 2.0 Java, Groovy, Javascript, Ruby, Scala, Kotlin, Ceylon
ActorFx[39] 不活跃 2013-11-13 Apache 2.0 .NET
Akka 活跃 2022-09-06[40] Apache 2.0 Java and Scala
Akka.NET[41] 活跃 2020-08-20[42] Apache 2.0 .NET
Apache Pekko[43] 活跃 2023-07-26[44] Apache 2.0 Java and Scala
Remact.Net[45] 不活跃 2016-06-26 MIT .NET, Javascript
Ateji PX[46] 不活跃  ?  ? Java
czmq[47] 活跃 2016-11-10 MPL-2 C
F# MailboxProcessor 活跃 同于F# (内建核心库) Apache License F#
Korus[48] 活跃 2010-02-04 GPL 3 Java
Kilim[49][50] 活跃 2018-11-09[51] MIT Java
ActorFoundry (基于Kilim) 不活跃 2008-12-28  ? Java
ActorKit[52] 活跃 2011-09-13[53] BSD Objective-C
Cloud Haskell[54] 活跃 2015-06-17[55] BSD Haskell
CloudI[56] 活跃 2023-10-27[57] MIT ATS, C/C++, Elixir/Erlang/LFE, Go, Haskell, Java, Javascript, OCaml, Perl, PHP, Python, Ruby
Clutter[58] 活跃 2017-05-12[59] LGPL 2.1 C, C++ (cluttermm), Python (pyclutter), Perl (perl-Clutter)
NAct[60] 不活跃 2012-02-28 LGPL 3.0 .NET
Nact[61] 活跃 2018-06-06[62] Apache 2.0 JavaScript/ReasonML
Retlang[63] 不活跃 2011-05-18[64] New BSD .NET
JActor[65] 不活跃 2013-01-22 LGPL Java
Jetlang[66] 活跃 2013-05-30[67] New BSD Java
Haskell-Actor[68] 不活跃? 2008 New BSD Haskell
GPars[69] 活跃 2014-05-09[70] Apache 2.0 Groovy
OOSMOS[71] 活跃 2019-05-09[72] GPL 2.0和商业(双许可证) C. C++ friendly
Panini[73] 活跃 2014-05-22 MPL 1.1 自己的编程语言
PARLEY[74] 不活跃? 2007-22-07 GPL 2.1 Python
Peernetic[75] 活跃 2007-06-29 LGPL 3.0 Java
PostSharp[76] 活跃 2014-09-24 商业 / Freemium .NET
Pulsar[77] 活跃 2016-07-09[78] New BSD Python
Pulsar[79] 活跃 2016-02-18[80] LGPL/Eclipse Clojure
Pykka[81] 活跃 2019-05-07[82] Apache 2.0 Python
Termite Scheme[83] 不活跃? 2009-05-21 LGPL Scheme (Gambit实现)
Theron[84] 不活跃[85] 2014-01-18[86] MIT[87] C++
Thespian[88] 活跃 2020-03-10 MIT Python
Quasar[89] 活跃 2018-11-02[90] LGPL/Eclipse Java
Libactor[91] 不活跃? 2009 GPL 2.0 C
Actor-CPP[92] 活跃 2012-03-10[93] GPL 2.0 C++
S4[94] 不活跃 2012-07-31[95] Apache 2.0 Java
C++ Actor Framework (CAF)[96] 活跃 2020-02-08[97] Boost Software License 1.0 and BSD 3-Clause C++11
Celluloid[98] 活跃 2018-12-20[99] MIT Ruby
LabVIEW Actor Framework[100] 活跃 2012-03-01[101] National Instruments SLA[102] LabVIEW
LabVIEW Messenger Library[103] 活跃 2021-05-24 BSD LabVIEW
Otavia[104] 活跃 2024-01-02 Apache 2.0 Scala
Orbit[105] 活跃 2019-05-28[106] New BSD Java
QP框架 活跃 2019-05-25[107] GPL 2.0和商业(双许可证) C and C++
libprocess[108] 活跃 2013-06-19 Apache 2.0 C++
SObjectizer[109] 活跃 2021-12-28[110] New BSD C++11
rotor[111] 活跃 2022-04-23[112] MIT License C++17
Orleans[113] 活跃 2023-07-11[114] MIT License C#/.NET
Skynet[115] 活跃 2016-07-11 MIT License C/Lua
Reactors.IO[116] 活跃 2016-06-14 BSD License Java/Scala
libagents[117] 活跃 2020-03-08 Free software license C++11
Proto.Actor[118] 活跃 2021-01-05 Free software license Go, C#, Python, JavaScript, Java, Kotlin
FunctionalJava[119] 活跃 2018-08-18[120] BSD 3-Clause Java
Riker[121] 活跃 2019-01-04 MIT License Rust
Comedy[122] 活跃 2019-03-09 EPL 1.0 JavaScript
VLINGO XOOM Actors[123] 活跃 2023-02-15 Mozilla Public License 2.0 Java, Kotlin, JVM languages, C# .NET
wasmCloud[124] 活跃 2021-03-23 Apache 2.0 WebAssembly (Rust, TinyGo, Zig, AssemblyScript)
ray[125] 活跃 2020-08-27 Apache 2.0 Python
DOTNETACTORS[126] 活跃 2021-06-14 MIT .NET, C#, Azure Service Bus
go-actor[127] 活跃 2022-08-16 GPL 3.0 Golang
Sento[128] 活跃 2022-11-21 Apache 2.0 Common Lisp
Xcraft Goblins[129] 活跃 2022-08-30 MIT JavaScript
Tarant[130] 活跃 2023-04-17 MIT Typescript, Javascript

注意这里没有列出全部框架和库。

并发编程语言用例

尽管Erlang语言设计者并未如此表述[131],因其进程间通信是通过无共享异步消息传递系统运作,它一般被引证为采用演员模型的典型代表之一。在Erlang中,所有进程都有一个自己的“邮箱”,它是从其他进程已经发送过来而仍未被消费的消息的队列。进程使用receive原语来检索匹配预期模式的消息。一个消息处理例程针对每个模式依次测试这些消息,直到其中有一个匹配。在消息被消费并从邮箱中移除之时进程恢复执行。消息可以包含任何Erlang结构,包括原始类型(整数,浮点数、字符、原子)、元组、列表和函数。

下面例子展示了Erlang对分布式进程的内建支持:

% 建立一个进程并启用函数web:start_server(Port, MaxConnections)
ServerProcess = spawn(web, start_server, [Port, MaxConnections]),

% 在机器RemoteNode上建立一个远程进程并启用函数web:start_server(Port, MaxConnections)
RemoteProcess = spawn(RemoteNode, web, start_server, [Port, MaxConnections]),

% (异步的)发送消息到ServerProcess。消息包含一个元组,它具有原子"pause"和数"10"。
ServerProcess ! {pause, 10},

% 接收发给这个进程的消息
receive
    a_message -> do_something;
    {data, DataContent} -> handle(DataContent);
    {hello, Text} -> io:format("Got hello message: ~s", [Text]);
    {goodbye, Text} -> io:format("Got goodbye message: ~s", [Text])
end.

原型的演员编程语言

Hewitt在2006年发表了一个原型的演员编程语言,用意在于直接表达演员行为的重要方面[132]。消息采用如下表示法:

<标签>[<元素>1 ... <元素>n]

编程语言的语义是通过将每个程序构造确定为有自己行为的演员来定义的。执行是通过在执行期间让Eval消息在程序构造之间传递来建模的。

环境演员

每个Eval消息都有一个充当环境的演员的地址,它能够进行标识符与值的绑定(binding)。environment演员是不可变的(immutable),也就是不变更的。

  • 当一个environment演员收到Request[Bind[identifier value] customer]的时候,建立一个新的环境演员environment’发送给customer,使得这个新环境演员收到Request[Lookup[identifier’] customer’]的时候,如果identifier同于identifier’,则发送给customer’一个Returned[value],否则发送给environment一个Request[Lookup[identifier’] customer’]
  • 当一个environment演员收到Request[Bind[<模式> String] customer]的时候,如果此<模式>形如Request[msg[paramerer] customer],匹配于String形如Request[msg[argument] customer],则建立一个新的环境演员environment’发送给customer,使得这个新环境演员收到Request[Lookup[parameter’] customer’]的时候,如果parameter’同于parameter,则发送给customer’一个Returned[argument],否则发送给customer一个Thrown[NotFound[<模式>]]
  • 当一个environment演员收到Request[Bind[identifier(parameter) value] customer]的时候,建立一个新的环境演员environment’发送给customer,使得这个新环境演员收到Request[Lookup[identifier’(argument)] customer’]的时候,如果identifier同于identifier’,则建立一个新的环境演员environment’’,发送给customer’一个Returned[value]和一个Returned[environment’’],否则发送给environment一个Request[Lookup[identifier’(argument)] customer’]。这个新环境演员environment’’在收到Request[Lookup[parameter’] customer’]的时候,如果parameter’同于parameter,则发送给customer’一个Returned[argument],否则发送给environment’一个Request[Lookup[parameter’] customer’]

上述环境演员建造在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]
send <接收者> <通信>
在收到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]
receiver ... <模式>i <表达式>i ...
在收到Request[Eval[environment] customer]的时候,发送给customer一个新演员theReceiver,使得
theReceiver收到通信内容com的时候,建立一个新演员bindingCustomer,并发送给environment一个Request[Bind[<模式>i com] bindingCustomer],而且
  1. 如果bindingCustomer收到Returned[environment’],发送给<表达式>i一个Request[Eval[environment’]]
  2. 不然如果bindingCustomer收到Thrown[...],尝试<模式>i+1
behavior ... <模式>i <表达式>i ...
在收到Request[Eval[environment] customer]的时候,发送给customer一个新演员theReceiver,使得
theReceiver收到Request[message customer’]的时候,建立一个新演员bindingCustomer,并发送给environment一个Request[bind[<模式>i message] customer’],而且
  1. 如果bindingCustomer收到Returned[environment’],发送给<表达式>i一个Request[Eval[environment’] customer’]
  2. 不然如果bindingCustomer收到Thrown[...],尝试<模式>i+1
{<表达式>1, <表达式>2}
在收到Request[Eval[environment] customer]的时候,发送给<表达式>1一个Request[Eval[environment]],而且并发的发送给<表达式>2一个Request[Eval[environment] customer]
let <标识符> = <表达式> in <表达式>
在收到message[Eval[environment] customer]的时候,建立一个新演员evalCustomer,并发送给<表达式>一个Request[Eval[environment] evalCustomer]
evalCustomer收到Returned[theValue]的时候,建立一个新演员bindingCustomer,并发送给environment一个Request[bind[<标识符> theValue] bindingCustomer]
bindingCustomer收到Returned[environment’]的时候,发送给<expression>一个Request[Eval[environment’] customer]
serializer <表达式>
在收到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,而theNextBehaviortheSerializer用作下次通信的行为演员。

例子程序

下面是简单的存储单元格(cell)的例子脚本(script),它可以包含任何演员地址:

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的图灵奖获奖演说中,他写到[133]

纯lambda演算现在只使用两种东西来建造:项和变量。我们在进程演算上也能实现同样的经济性吗?Carl Hewitt凭借其演员模型,很久以前就应对了这个挑战;他宣告了值、在值上的算子和进程,都应该是同一种东西:即演员。

这个目标打动了我,因为它蕴涵了表达式有着同质性和完整性 ... 但是很久以后我才明白了如何依据代数演算来达成这个目标 ...

因此本着Hewitt的精神,我们的第一步,就是要求由项指示或由名字访问的所有东西,包括值、寄存器、算子、进程、对象,都是同一种东西;它们都应当是进程。

实践

演员模型在商业实践中已经有了巨大的影响。例如,Twitter将演员用于可伸缩性应用[134]。还有,Microsoft在其开发的异步代理库中使用了演员模型[135]

参见

引用

  1. Carl Hewitt; Peter Bishop and Richard Steiger. (PDF). IJCAI. 1973 [2020-05-06]. (原始内容存档 (PDF)于2021-02-25).
  2. Carl Hewitt. Viewing Control Structures as Patterns of Passing Messages 页面存档备份,存于. Journal of Artificial Intelligence. June 1977.
  3. William Clinger. . Mathematics Doctoral Dissertation. MIT. June 1981. hdl:1721.1/6935.
  4. Irene Greif. . EECS Doctoral Dissertation. MIT. August 1975.
  5. Henry Baker; Carl Hewitt. . IFIP. August 1977.
  6. (PDF). 10 May 1977 [2020-05-04]. (原始内容存档 (PDF)于2016-06-24).
  7. Gul Agha. . Doctoral Dissertation. MIT Press. 1986. hdl:1721.1/6952.
  8. . Osl.cs.uiuc.edu. [2012-12-02]. (原始内容存档于2013-02-22).
  9. Henry Lieberman. . MIT AI memo 625. June 1981.
  10. Henry Lieberman. . MIT AI memo 626. June 1981.
  11. Jean-Pierre Briot. Acttalk: A framework for object-oriented concurrent programming-design and experience 2nd France-Japan workshop. 1999.
  12. Ken Kahn. A Computational Theory of Animation MIT EECS Doctoral Dissertation. August 1979.
  13. William Athas and Nanette Boden Cantor: An Actor Programming System for Scientific Computing in Proceedings of the NSF Workshop on Object-Based Concurrent Programming. 1988. Special Issue of SIGPLAN Notices.
  14. Darrell Woelk. Developing InfoSleuth Agents Using Rosette: An Actor Based Language Proceedings of the CIKM '95 Workshop on Intelligent Information Agents. 1995.
  15. Dedecker J., Van Cutsem T., Mostinckx S., D'Hondt T., De Meuter W. Ambient-oriented Programming in AmbientTalk. In “Proceedings of the 20th European Conference on Object-Oriented Programming (ECOOP), Dave Thomas (Ed.), Lecture Notes in Computer Science Vol. 4067, pp. 230-254, Springer-Verlag.”, 2006
  16. Darryl K. Taft. . Eweek.com. 2009-04-17 [2012-12-02]. (原始内容存档于2012-07-29).
  17. Brandauer, Stephan; et al. . Formal Methods for Multicore Programming. (Springer International Publishing). 2015: 1–56.
  18. . Dalnefre.com. [2012-12-02]. (原始内容存档于2021-02-07).
  19. . [2022-01-11]. (原始内容存档于2018-09-04).
  20. Clebsch, Sylvan; Drossopoulou, Sophia; Blessing, Sebastian; McNeil, Andy. . . 2015: 1–12. ISBN 9781450339018. doi:10.1145/2824815.2824816. by Sylvan Clebsch, Sophia Drossopoulou, Sebastian Blessing, Andy McNeil
  21. . 2019-03-08 [2020-05-06]. (原始内容存档于2021-01-15).
  22. . 2019-03-12 [2020-05-06]. (原始内容存档于2021-03-23).
  23. Carlos Varela and Gul Agha. . ACM SIGPLAN Notices. OOPSLA'2001 Intriguing Technology Track Proceedings. 2001, 36.
  24. Philipp Haller and Martin Odersky. (PDF). Proc. JMLC 2006. September 2006 [2014-08-04]. (原始内容存档 (PDF)于2020-11-09).
  25. Philipp Haller and Martin Odersky. (PDF). Technical report LAMP 2007. January 2007 [2014-08-04]. (原始内容 (PDF)存档于2011-06-07).
  26. ReActed 页面存档备份,存于
  27. Acteur 页面存档备份,存于
  28. . crates.io. [2020-04-16]. (原始内容存档于2021-02-05).
  29. Bastion 页面存档备份,存于
  30. Bulut, Mahmut. . Crates.io. 2019-12-15 [2019-12-15]. (原始内容存档于2021-02-05).
  31. Actix 页面存档备份,存于
  32. . crates.io. [2019-06-03]. (原始内容存档于2021-02-05).
  33. Aojet 页面存档备份,存于
  34. Actor 页面存档备份,存于
  35. Actor4j 页面存档备份,存于
  36. Actr 页面存档备份,存于
  37. . Github.com. [2019-04-16]. (原始内容存档于2020-10-26).
  38. Vert.x 页面存档备份,存于
  39. ActorFx 页面存档备份,存于
  40. . Akka. 2022-09-06 [2022-12-23]. (原始内容存档于2022-09-24).
  41. Akka.NET 页面存档备份,存于
  42. Akka.NET v1.4.10 Stable Release , Akka.NET, 2020-10-01 [2020-10-01], (原始内容存档于2021-02-24)
  43. . [2024-02-13]. (原始内容存档于2024-02-10).
  44. , Apache Software Foundation, [2024-02-13], (原始内容存档于2023-12-04)
  45. Remact.Net 页面存档备份,存于
  46. Ateji PX
  47. czmq 页面存档备份,存于
  48. Korus 页面存档备份,存于
  49. Kilim 页面存档备份,存于
  50. Srinivasan, Sriram; Alan Mycroft. (PDF). . Cyprus. 2008 [2016-02-25]. (原始内容存档 (PDF)于2020-10-28).
  51. . Github.com. [2019-06-03]. (原始内容存档于2020-10-16).
  52. ActorKit 页面存档备份,存于
  53. . Github.com. [2016-02-25].
  54. Cloud Haskell
  55. . Github.com. [2012-12-02]. (原始内容存档于2017-03-24).
  56. CloudI 页面存档备份,存于
  57. . sourceforge.net. [2024-01-03]. (原始内容存档于2024-01-04).
  58. Clutter 页面存档备份,存于
  59. . gitlab.gnome.org. [2019-06-03]. (原始内容存档于2019-06-03).
  60. NAct 页面存档备份,存于
  61. Nact 页面存档备份,存于
  62. . [2019-06-03]. (原始内容存档于2020-11-27).
  63. Retlang 页面存档备份,存于
  64. . [2016-02-25]. (原始内容存档于2015-11-24).
  65. JActor
  66. Jetlang 页面存档备份,存于
  67. . 2012-02-14 [2016-02-25]. (原始内容存档于2016-01-14).
  68. Haskell-Actor 页面存档备份,存于
  69. GPars 页面存档备份,存于
  70. . GitHub. [2016-02-25]. (原始内容存档于2020-09-04).
  71. OOSMOS 页面存档备份,存于
  72. . GitHub. [2019-06-03]. (原始内容存档于2020-11-13).
  73. Panini 页面存档备份,存于
  74. PARLEY
  75. Peernetic
  76. PostSharp 页面存档备份,存于
  77. Pulsar 页面存档备份,存于
  78. . (原始内容存档于2015-07-04).
  79. Pulsar 页面存档备份,存于
  80. . (原始内容存档于2013-07-26).
  81. Pykka 页面存档备份,存于
  82. . pykka.org. [2019-06-03]. (原始内容存档于2021-02-05).
  83. Termite Scheme 页面存档备份,存于
  84. Theron
  85. . [2018-08-29]. (原始内容存档于2019-03-31).
  86. . Theron-library.com. [2016-02-25]. (原始内容存档于2016-03-16).
  87. . Theron-library.com. [2016-02-25]. (原始内容存档于2016-03-04).
  88. Thespian 页面存档备份,存于
  89. Quasar 页面存档备份,存于
  90. . [2019-06-03]. (原始内容存档于2020-12-15).
  91. Libactor 页面存档备份,存于
  92. Actor-CPP 页面存档备份,存于
  93. . [2012-12-02]. (原始内容存档于2015-11-18).
  94. S4 页面存档备份,存于
  95. . apache.org. [2016-01-16]. (原始内容存档于2016-03-06).
  96. C++ Actor Framework (CAF) 页面存档备份,存于
  97. . Github.com. [2020-03-07]. (原始内容存档于2021-03-26).
  98. Celluloid 页面存档备份,存于
  99. . RubyGems.org. [2019-06-03]. (原始内容存档于2020-09-29).
  100. LabVIEW Actor Framework
  101. . Decibel.ni.com. 2011-09-23 [2016-02-25]. (原始内容存档于2016-10-13).
  102. National Instruments SLA 页面存档备份,存于
  103. LabVIEW Messenger Library 页面存档备份,存于
  104. . [2024-02-13]. (原始内容存档于2024-01-10).
  105. Orbit 页面存档备份,存于
  106. . GitHub. [2019-06-03].
  107. . Sourceforge.net. [2019-06-03]. (原始内容存档于2021-02-24).
  108. libprocess 页面存档备份,存于
  109. SObjectizer 页面存档备份,存于
  110. . GitHub. [2022-05-11]. (原始内容存档于2020-10-19).
  111. rotor 页面存档备份,存于
  112. . GitHub. [2022-05-17]. (原始内容存档于2020-09-15).
  113. Orleans 页面存档备份,存于
  114. . GitHub. [2022-09-21]. (原始内容存档于2020-12-04).
  115. Skynet 页面存档备份,存于
  116. Reactors.IO 页面存档备份,存于
  117. libagents 页面存档备份,存于
  118. Proto.Actor 页面存档备份,存于
  119. FunctionalJava 页面存档备份,存于
  120. . GitHub. [2018-08-23]. (原始内容存档于2021-01-15).
  121. Riker 页面存档备份,存于
  122. Comedy 页面存档备份,存于
  123. . [2021-01-15]. (原始内容存档于2020-11-29).
  124. . [2023-07-02]. (原始内容存档于2023-07-02).
  125. ray 页面存档备份,存于
  126. . [2022-12-23]. (原始内容存档于2022-12-24).
  127. . [2022-12-23]. (原始内容存档于2022-12-23).
  128. . [2022-12-23]. (原始内容存档于2023-04-05).
  129. . [2022-12-23]. (原始内容存档于2023-06-07).
  130. . [2023-07-02]. (原始内容存档于2023-05-27).
  131. Armstrong, Joe. . Communications of the ACM. September 2010, 53 (9): 68–75 [2020-05-07]. doi:10.1145/1810891.1810910. (原始内容存档于2020-06-09). Erlang is conceptually similar to the occam programming language, though it recasts the ideas of CSP in a functional framework and uses asynchronous message passing instead of the synchronous message passing in CSP.
  132. Carl Hewitt. The repeated demise of logic programming and why it will be reincarnated. What Went Wrong and Why: Lessons from AI Research and Applications. Technical Report SS-06-08. AAAI Press. March 2006.
  133. Milner, Robin. . Communications of the ACM. 1993, 36: 78–89. doi:10.1145/151233.151240.
  134. . Waimingmok.wordpress.com. 2009-06-27 [2012-12-02]. (原始内容存档于2021-02-05).
  135. "Actor-Based Programming with the Asynchronous Agents Library 页面存档备份,存于" MSDN September 2010.

延伸阅读

外部链接

This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.