演员模型

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

演員模型在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人工智能实验室、斯坦福国际研究所、斯坦福大学、伊利诺伊大学厄巴纳-香槟分校、巴黎第六大学、比萨大学、东京大学研究室、荷兰数学和计算机科学研究学会和其他一些地方。

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

早期的演员模型编程语言
 
 Act 1，2，3
Acttalk
Ani
Cantor
Rosette

后期的演员模型编程语言
 
 
 
 
 
 D
 E
 Elixir
 Encore
 Erlang
 
 Humus
 Io
 Pony
 
 
 P#
 
 Reia
 Rust
 SALSA
 Scala
 Scratch

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

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

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

下面例子展示了Erlang对分布式进程的内建支持：
% 建立一个进程并启用函数web:start_server(Port, MaxConnections)
ServerProcess = spawn(web, start_server, [Port, MaxConnections]),

% 建立一个远程进程并启用函数
% web:start_server(Port, MaxConnections)于机器RemoteNode
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年发表了一个原型的演员编程语言，用意在于直接表达演员行为的重要方面。消息采用如下表示法：

<kbd><标签>[<元素>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]，而且
如果bindingCustomer收到Returned[environment’]，发送给<表达式>i一个Request[Eval[environment’]]
不然如果bindingCustomer收到Thrown[...]，尝试<模式>i+1。

 behavior ... <模式>i <表达式>i ...
在收到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。

{<表达式>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，而theNextBehavior被theSerializer用作下次通信的行为演员。

例子程序
下面是简单的存储单元格（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的图灵奖获奖演说中，他写到：
纯lambda演算现在只使用两种东西来建造：项和变量。我们在进程演算上也能实现同样的经济性吗？Carl Hewitt凭借其演员模型，很久以前就应对了这个挑战；他宣告了值、在值上的算子和进程，都应该是同一种东西：即演员。
这个目标打动了我，因为它蕴涵了表达式有着同质性和完整性 ... 但是很久以后我才明白了如何依据代数演算来达成这个目标 ...
因此本着Hewitt的精神，我们的第一步，就是要求由项指示或由名字访问的所有东西，包括值、寄存器、算子、进程、对象，都是同一种东西；它们都应当是进程。

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

参见
 数据流程编程
 并行编程模型

引用

延伸阅读

Gul Agha. Actors: A Model of Concurrent Computation in Distributed Systems . MIT Press 1985.
Paul Baran. On Distributed Communications Networks IEEE Transactions on Communications Systems. March 1964.
William A. Woods. Transition network grammars for natural language analysis  CACM. 1970.
Carl Hewitt. Procedural Embedding of Knowledge In Planner  IJCAI 1971.
G.M. Birtwistle, Ole-Johan Dahl, B. Myhrhaug and Kristen Nygaard. SIMULA Begin Auerbach Publishers Inc, 1973.
Carl Hewitt, et al. Actor Induction and Meta-evaluation Conference Record of ACM Symposium on Principles of Programming Languages, January 1974.
Carl Hewitt, Behavioral Semantics of Nonrecursive Control Structure  Proceedings of Colloque sur la Programmation, April 1974.
Irene Greif and Carl Hewitt.  Actor Semantics of PLANNER-73  Conference Record of ACM Symposium on Principles of Programming Languages. January 1975.
Carl Hewitt. How to Use What You Know  IJCAI. September, 1975.
Alan Kay and Adele Goldberg.  Smalltalk-72 Instruction Manual. Xerox PARC Memo SSL-76-6.  May 1976.
Edsger Dijkstra. A discipline of programming Prentice Hall. 1976.
Carl Hewitt and Henry Baker Actors and Continuous Functionals Proceeding of IFIP Working Conference on Formal Description of Programming Concepts. August 1–5, 1977.
Carl Hewitt and Russ Atkinson.  Synchronization in Actor Systems Proceedings of the 4th ACM SIGACT-SIGPLAN symposium on Principles of programming languages. 1977
Carl Hewitt and Russ Atkinson.  Specification and Proof Techniques for Serializers  IEEE Journal on Software Engineering. January 1979.
Ken Kahn. A Computational Theory of Animation  MIT EECS Doctoral Dissertation. August 1979.
Carl Hewitt, Beppe Attardi, and Henry Lieberman.  Delegation in Message Passing Proceedings of First International Conference on Distributed Systems Huntsville, AL. October 1979.
Nissim Francez, C.A.R. Hoare, Daniel Lehmann, and Willem-Paul de Roever. Semantics of nondetermiism, concurrency, and communication Journal of Computer and System Sciences.  December 1979.
George Milne and Robin Milner. Concurrent processes and their syntax JACM. April 1979.
Daniel Theriault. A Primer for the Act-1 Language MIT AI memo 672. April 1982.
Daniel Theriault.  Issues in the Design and Implementation of Act 2  MIT AI technical report 728. June 1983.
Henry Lieberman. An Object-Oriented Simulator for the Apiary Conference of the American Association for Artificial Intelligence, Washington, D. C., August 1983
Carl Hewitt and Peter de Jong. Analyzing the Roles of Descriptions and Actions in Open Systems  Proceedings of the National Conference on Artificial Intelligence. August 1983.
Carl Hewitt and Henry Lieberman. Design Issues in Parallel Architecture for Artificial Intelligence MIT AI memo 750.  Nov. 1983.
C.A.R. Hoare. Communicating Sequential Processes  Prentice Hall. 1985.
Carl Hewitt. The Challenge of Open Systems Byte. April 1985.  Reprinted in The foundation of artificial intelligence: a sourcebook Cambridge University Press. 1990.
Carl Manning. Traveler: the actor observatory ECOOP 1987. Also appears in Lecture Notes in Computer Science, vol. 276.
William Athas and Charles Seitz Multicomputers: message-passing concurrent computers  IEEE Computer August 1988.
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.
Jean-Pierre Briot.  From objects to actors: Study of a limited symbiosis in Smalltalk-80  Rapport de Recherche 88-58, RXF-LITP, Paris, France, September 1988
William Dally and Wills, D. Universal mechanisms for concurrency  PARLE 1989.
W. Horwat, A. Chien, and W. Dally. Experience with CST: Programming and Implementation PLDI. 1989.
Carl Hewitt. Towards Open Information Systems Semantics Proceedings of 10th International Workshop on Distributed Artificial Intelligence. October 23–27, 1990. Bandera, Texas.
Akinori Yonezawa, Ed. ABCL: An Object-Oriented Concurrent System MIT Press. 1990.
 K. Kahn and Vijay A. Saraswat, "Actors as a special case of concurrent constraint (logic) programming", in SIGPLAN Notices, October 1990. Describes Janus.
Carl Hewitt. Open Information Systems Semantics Journal of Artificial Intelligence. January 1991.
Carl Hewitt and Jeff Inman.  DAI Betwixt and Between: From "Intelligent Agents" to Open Systems Science  IEEE Transactions on Systems, Man, and Cybernetics. Nov./Dec. 1991.
Carl Hewitt and Gul Agha. Guarded Horn clause languages: are they deductive and Logical? International Conference on Fifth Generation Computer Systems, Ohmsha 1988. Tokyo.  Also in Artificial Intelligence at MIT, Vol. 2. MIT Press 1991.
William Dally, et al. The Message-Driven Processor: A Multicomputer Processing Node with Efficient Mechanisms  IEEE Micro. April 1992.
S. Miriyala, G. Agha, and Y.Sami. Visualizing actor programs using predicate transition nets  Journal of Visual Programming. 1992.
Carl Hewitt and Carl Manning.  Negotiation Architecture for Large-Scale Crisis Management AAAI-94 Workshop on Models of Conflict Management in Cooperative Problem Solving. Seattle, WA. Aug. 4, 1994.
Carl Hewitt and Carl Manning.  Synthetic Infrastructures for Multi-Agency Systems Proceedings of ICMAS '96. Kyoto, Japan. December 8–13, 1996.
S. Frolund. Coordinating Distributed Objects: An Actor-Based Approach for Synchronization MIT Press. November 1996.
W. Kim. ThAL: An Actor System for Efficient and Scalable Concurrent Computing  PhD thesis. University of Illinois at Urbana Champaign. 1997.
Jean-Pierre Briot. Acttalk: A framework for object-oriented concurrent programming-design and experience 2nd France-Japan workshop. 1999.
N. Jamali, P. Thati, and G. Agha. An actor based architecture for customizing and controlling agent ensembles  IEEE Intelligent Systems. 14(2). 1999.
Don Box, David Ehnebuske, Gopal Kakivaya, Andrew Layman, Noah Mendelsohn, Henrik Nielsen, Satish Thatte, Dave Winer. Simple Object Access Protocol (SOAP) 1.1 W3C Note. May 2000.
M. Astley, D. Sturman, and G. Agha. Customizable middleware for modular distributed software  CACM. 44(5) 2001.
Edward Lee, S. Neuendorffer, and M. Wirthlin. Actor-oriented design of embedded hardware and software systems  Journal of Circuits, Systems, and Computers. 2002.
P. Thati, R. Ziaei, and G. Agha. A Theory of May Testing for Actors Formal Methods for Open Object-based Distributed Systems. March 2002.
P. Thati, R. Ziaei, and G. Agha. A theory of may testing for asynchronous calculi with locality and no name matching Algebraic Methodology and Software Technology. Springer Verlag. September 2002. LNCS 2422.
Stephen Neuendorffer.  Actor-Oriented Metaprogramming  PhD Thesis. University of California, Berkeley. December, 2004
Carl Hewitt (2006a)  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.
Carl Hewitt (2006b) What is Commitment? Physical, Organizational, and Social   COIN@AAMAS.  April 27, 2006b.
Carl Hewitt (2007a) What is Commitment? Physical, Organizational, and Social (Revised) Pablo Noriega .et al. editors. LNAI 4386. Springer-Verlag. 2007.
Carl Hewitt (2007b) Large-scale Organizational Computing requires Unstratified Paraconsistency and Reflection  COIN@AAMAS'07.
D. Charousset, T. C. Schmidt, R. Hiesgen and M. Wählisch. Native actors: a scalable software platform for distributed, heterogeneous environments in AGERE! '13 Proceedings of the 2013 workshop on Programming based on actors, agents, and decentralized control.

外部链接

并发计算
计算模型
演员模型