• Actor model


    Actor model - Wikipedia https://en.wikipedia.org/wiki/Actor_model

    计算机科学中,演员模型(英语:Actor model)是一种并发运算上的模型。“演员”是一种程序上的抽象概念,被视为并发运算的基本单元:当一个演员接收到一则消息,它可以做出一些决策、创建更多的演员、发送更多的消息、决定要如何回答接下来的消息。演员可以修改它们自己的私有状态,但是只能通过消息间接的相互影响(避免了基于锁的同步)。

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

    基本概念[编辑]

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

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

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

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

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

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

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

    历史[编辑]

    演员模型受到了编程语言LispSimula、早期版本的Smalltalk基于权力的系统分组交换的影响。它的发展是“由几十、几百、甚至几千独立的微处理机构成的高度并行计算机器的前景所推动的,每个处理机都有自己局部内存和通信处理器,通过高性能网络进行通信。”[3]从那时起,随着通过多核众核计算机架构的大规模并发的到来,人们已经复兴了对演员模型的兴趣。

    跟从Hewitt、Bishop和Steiger在1973年的出版物,Irene Greif为演员模型开发了一个操作语义作为他的博士论文研究的一部分[4]。两年以后,Henry Baker和Hewitt出版了针对演员系统的一组公理法则[5][6]。其他的主要里程碑包括William Clinger的1981年学位论文,介入了基于Power domains指称语义[3],和Gul Agha的1985年学位论文,它进一步的发展了基于transition的语义模型,补充了Clinger的模型[7]。这些工作导致了演员模型理论的全面发展。

    主要的软件实现工作是麻省理工学院(MIT)消息传递语义小组的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完成的。分别由加州理工学院(Caltech)的Chuck Seitz和MIT的Bill Dally领导的研究组,致力于构造进一步发展在这个模型中的消息传递的计算机架构。参见演员模型实现

    关于演员模型的研究已经在加州理工学院京都大学微电子及计算机技术公司(MCC)、MIT人工智能实验室SRI斯坦福大学伊利诺伊大学厄巴纳-香槟分校[8]巴黎第六大学比萨大学东京大学米泽研究室、荷兰数学和计算机科学研究学会(CWI)和其他一些地方开展了。

    影响[编辑]

    演员模型在理论发展和实践软件开发中都有影响。

    理论[编辑]

    演员模型影响了π-演算和后续的进程演算的发展。在Robin Milner的图灵奖获奖演讲中,他写到[9]

    现在,纯粹的lambda演算只使用两种东西来建造:项(term)和变量。我们在进程演算上能实现如此的经济节约吗?Carl Hewitt,与他的演员模型一起,很久以前就响应了这个挑战;他宣布值、在值上的算子(operator)和进程都应该是同一种东西:演员。

    这个目标打动了我,因为它意味着表达式的同质性和完整性 ... 但是很久以前我就能领会到如何依据代数演算来达成这个目标 ...

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

    实践[编辑]

    演员模型在商业实践中已经有了巨大的影响。例如,Twitter将演员用于可伸缩性应用[10]。还有,Microsoft在开发的异步代理库中使用了演员模型[11]。下面章节列出了很多其他的演员库。

    使用演员模型编程[编辑]

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

    早期演员模型编程语言[编辑]

    后期演员模型编程语言[编辑]

    演员模型库及框架[编辑]

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

    名称状态最新发行许可证语言
    ReActed 活跃 2021-09-05 Apache 2.0 Java
    Acteur 活跃 2020-04-16[29] Apache-2.0 / MIT Rust
    Bastion 活跃 2020-08-12[30] Apache-2.0 / MIT Rust
    Actix 活跃 2019-05-30[31] MIT Rust
    Aojet 活跃 2016-10-17 MIT Swift
    Actor 活跃 2017-03-09 MIT Java
    Actor4j 活跃 2020-01-31 Apache 2.0 Java
    Actr 活跃 2019-04-09[32] Apache 2.0 Java
    Vert.x 活跃 2018-02-13 Apache 2.0 Java, Groovy, Javascript, Ruby, Scala, Kotlin, Ceylon
    ActorFx 不活跃 2013-11-13 Apache 2.0 .NET
    Akka 活跃 2019-05-21[33] Apache 2.0 Java and Scala
    Akka.NET 活跃 2020-08-20[34] Apache 2.0 .NET
    Remact.Net 不活跃 2016-06-26 MIT .NET, Javascript
    Ateji PX 不活跃 ? ? Java
    czmq 活跃 2016-11-10 MPL-2 C
    F# MailboxProcessor 活跃 same as F# (built-in core library) Apache License F#
    Korus 活跃 2010-02-04 GPL 3 Java
    Kilim[35] 活跃 2018-11-09[36] MIT Java
    ActorFoundry (based on Kilim) 不活跃 2008-12-28 ? Java
    ActorKit 活跃 2011-09-13[37] BSD Objective-C
    Cloud Haskell 活跃 2015-06-17[38] BSD Haskell
    CloudI 活跃 2021-05-27[39] MIT ATS, C/C++, Elixir/Erlang/LFE, Go, Haskell, Java, Javascript, OCaml, Perl, PHP, Python, Ruby
    Clutter 活跃 2017-05-12[40] LGPL 2.1 C, C++ (cluttermm), Python (pyclutter), Perl (perl-Clutter)
    NAct 不活跃 2012-02-28 LGPL 3.0 .NET
    Nact 活跃 2018-06-06[41] Apache 2.0 JavaScript/ReasonML
    Retlang 不活跃 2011-05-18[42] New BSD .NET
    JActor 不活跃 2013-01-22 LGPL Java
    Jetlang 活跃 2013-05-30[43] New BSD Java
    Haskell-Actor 活跃? 2008 New BSD Haskell
    GPars 活跃 2014-05-09[44] Apache 2.0 Groovy
    OOSMOS 活跃 2019-05-09[45] GPL 2.0和商业(双许可证) C. C++ friendly
    Panini 活跃 2014-05-22 MPL 1.1 自己的编程语言
    PARLEY 活跃? 2007-22-07 GPL 2.1 Python
    Peernetic 活跃 2007-06-29 LGPL 3.0 Java
    PostSharp 活跃 2014-09-24 商业 / Freemium .NET
    Pulsar 活跃 2016-07-09[46] New BSD Python
    Pulsar 活跃 2016-02-18[47] LGPL/Eclipse Clojure
    Pykka 活跃 2019-05-07[48] Apache 2.0 Python
    Termite Scheme 活跃? 2009-05-21 LGPL Scheme (Gambit实现)
    Theron 不活跃[49] 2014-01-18[50] MIT[51] C++
    Thespian 活跃 2020-03-10 MIT Python
    Quasar 活跃 2018-11-02[52] LGPL/Eclipse Java
    Libactor 活跃? 2009 GPL 2.0 C
    Actor-CPP 活跃 2012-03-10[53] GPL 2.0 C++
    S4 不活跃 2012-07-31[54] Apache 2.0 Java
    C++ Actor Framework (CAF) 活跃 2020-02-08[55] Boost Software License 1.0 and BSD 3-Clause C++11
    Celluloid 活跃 2018-12-20[56] MIT Ruby
    LabVIEW Actor Framework 活跃 2012-03-01[57] National Instruments SLA LabVIEW
    LabVIEW Messenger Library 活跃 2021-05-24 BSD LabVIEW
    Orbit 活跃 2019-05-28[58] New BSD Java
    用于实时嵌入式系统的QP框架 活跃 2019-05-25[59] GPL 2.0和商业(双许可证) C and C++
    libprocess 活跃 2013-06-19 Apache 2.0 C++
    SObjectizer 活跃 2020-05-09[60] New BSD C++11
    rotor 活跃 2020-10-23[61] MIT License C++17
    Orleans 活跃 2021-09-03[62] MIT License C#/.NET
    Skynet 活跃 2016-07-11 MIT License C/Lua
    Reactors.IO 活跃 2016-06-14 BSD License Java/Scala
    libagents 活跃 2020-03-08 Free software license C++11
    Proto.Actor 活跃 2021-01-05 Free software license Go, C#, Python, JavaScript, Java, Kotlin
    FunctionalJava 活跃 2018-08-18[63] BSD 3-Clause Java
    Riker 活跃 2019-01-04 MIT License Rust
    Comedy 活跃 2019-03-09 EPL 1.0 JavaScript
    vlingo 活跃 2020-07-26 Mozilla Public License 2.0 Java, Kotlin, soon .NET
    waSCC 活跃 2020-08-30 Apache 2.0 WebAssembly (Rust, TinyGo, Zig, AssemblyScript)
    ray 活跃 2020-08-27 Apache 2.0 Python

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

    并发编程语言用例[编辑]

    尽管设计者并未如此表述[64]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年发表了一个原型的演员编程语言,用意在于直接表达演员行为的重要方面[65]。消息采用如下表示法:

    <标签>[<元素>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。

    Actor model

    From Wikipedia, the free encyclopedia
     
     
     
    Jump to navigationJump to search

    The actor model in computer science is a mathematical model of concurrent computation that treats actor as the universal primitive of concurrent computation. In response to a message it receives, an actor can: make local decisions, create more actors, send more messages, and determine how to respond to the next message received. Actors may modify their own private state, but can only affect each other indirectly through messaging (removing the need for lock-based synchronization).

    The actor model originated in 1973.[1] It has been used both as a framework for a theoretical understanding of computation and as the theoretical basis for several practical implementations of concurrent systems. The relationship of the model to other work is discussed in actor model and process calculi.

    History[edit]

    According to Carl Hewitt, unlike previous models of computation, the actor model was inspired by physics, including general relativity and quantum mechanics.[citation needed] It was also influenced by the programming languages LispSimula, early versions of Smalltalkcapability-based systems, and packet switching. Its development was "motivated by the prospect of highly parallel computing machines consisting of dozens, hundreds, or even thousands of independent microprocessors, each with its own local memory and communications processor, communicating via a high-performance communications network."[2] Since that time, the advent of massive concurrency through multi-core and manycore computer architectures has revived interest in the actor model.

    Following Hewitt, Bishop, and Steiger's 1973 publication, Irene Greif developed an operational semantics for the actor model as part of her doctoral research.[3] Two years later, Henry Baker and Hewitt published a set of axiomatic laws for actor systems.[4][5] Other major milestones include William Clinger's 1981 dissertation introducing a denotational semantics based on power domains[2] and Gul Agha's 1985 dissertation which further developed a transition-based semantic model complementary to Clinger's.[6] This resulted in the full development of actor model theory.

    Major software implementation work was done by Russ Atkinson, Giuseppe Attardi, Henry Baker, Gerry Barber, Peter Bishop, Peter de Jong, Ken Kahn, Henry Lieberman, Carl Manning, Tom Reinhardt, Richard Steiger and Dan Theriault in the Message Passing Semantics Group at Massachusetts Institute of Technology (MIT). Research groups led by Chuck Seitz at California Institute of Technology (Caltech) and Bill Dally at MIT constructed computer architectures that further developed the message passing in the model. See Actor model implementation.

    Research on the actor model has been carried out at California Institute of TechnologyKyoto University Tokoro Laboratory, Microelectronics and Computer Technology Corporation (MCC), MIT Artificial Intelligence LaboratorySRIStanford UniversityUniversity of Illinois at Urbana–Champaign,[7] Pierre and Marie Curie University (University of Paris 6), University of PisaUniversity of Tokyo Yonezawa Laboratory, Centrum Wiskunde & Informatica (CWI) and elsewhere.

    Fundamental concepts[edit]

    The actor model adopts the philosophy that everything is an actor. This is similar to the everything is an object philosophy used by some object-oriented programming languages.

    An actor is a computational entity that, in response to a message it receives, can concurrently:

    • send a finite number of messages to other actors;
    • create a finite number of new actors;
    • designate the behavior to be used for the next message it receives.

    There is no assumed sequence to the above actions and they could be carried out in parallel.

    Decoupling the sender from communications sent was a fundamental advance of the actor model enabling asynchronous communication and control structures as patterns of passing messages.[8]

    Recipients of messages are identified by address, sometimes called "mailing address". Thus an actor can only communicate with actors whose addresses it has. It can obtain those from a message it receives, or if the address is for an actor it has itself created.

    The actor model is characterized by inherent concurrency of computation within and among actors, dynamic creation of actors, inclusion of actor addresses in messages, and interaction only through direct asynchronous message passing with no restriction on message arrival order.

    Formal systems[edit]

    Over the years, several different formal systems have been developed which permit reasoning about systems in the actor model. These include:

    There are also formalisms that are not fully faithful to the actor model in that they do not formalize the guaranteed delivery of messages including the following (See Attempts to relate actor semantics to algebra and linear logic):

    Applications[edit]

    The actor model can be used as a framework for modeling, understanding, and reasoning about a wide range of concurrent systems.[15] For example:

    • Electronic mail (email) can be modeled as an actor system. Accounts are modeled as actors and email addresses as actor addresses.
    • Web services can be modeled with Simple Object Access Protocol (SOAP) endpoints modeled as actor addresses.
    • Objects with locks (e.g., as in Java and C#) can be modeled as a serializer, provided that their implementations are such that messages can continually arrive (perhaps by being stored in an internal queue). A serializer is an important kind of actor defined by the property that it is continually available to the arrival of new messages; every message sent to a serializer is guaranteed to arrive.[16]
    • Testing and Test Control Notation (TTCN), both TTCN-2 and TTCN-3, follows actor model rather closely. In TTCN actor is a test component: either parallel test component (PTC) or main test component (MTC). Test components can send and receive messages to and from remote partners (peer test components or test system interface), the latter being identified by its address. Each test component has a behaviour tree bound to it; test components run in parallel and can be dynamically created by parent test components. Built-in language constructs allow the definition of actions to be taken when an expected message is received from the internal message queue, like sending a message to another peer entity or creating new test components.

    Message-passing semantics[edit]

    The actor model is about the semantics of message passing.

    Unbounded nondeterminism controversy[edit]

    Arguably, the first concurrent programs were interrupt handlers. During the course of its normal operation a computer needed to be able to receive information from outside (characters from a keyboard, packets from a network, etc). So when the information arrived the execution of the computer was interrupted and special code (called an interrupt handler) was called to put the information in a data buffer where it could be subsequently retrieved.

    In the early 1960s, interrupts began to be used to simulate the concurrent execution of several programs on one processor.[17] Having concurrency with shared memory gave rise to the problem of concurrency control. Originally, this problem was conceived as being one of mutual exclusion on a single computer. Edsger Dijkstra developed semaphores and later, between 1971 and 1973,[18] Tony Hoare[19] and Per Brinch Hansen[20] developed monitors to solve the mutual exclusion problem. However, neither of these solutions provided a programming language construct that encapsulated access to shared resources. This encapsulation was later accomplished by the serializer construct ([Hewitt and Atkinson 1977, 1979] and [Atkinson 1980]).

    The first models of computation (e.g.Turing machines, Post productions, the lambda calculusetc.) were based on mathematics and made use of a global state to represent a computational step (later generalized in [McCarthy and Hayes 1969] and [Dijkstra 1976] see Event orderings versus global state). Each computational step was from one global state of the computation to the next global state. The global state approach was continued in automata theory for finite-state machines and push down stack machines, including their nondeterministic versions. Such nondeterministic automata have the property of bounded nondeterminism; that is, if a machine always halts when started in its initial state, then there is a bound on the number of states in which it halts.

    Edsger Dijkstra further developed the nondeterministic global state approach. Dijkstra's model gave rise to a controversy concerning unbounded nondeterminism (also called unbounded indeterminacy), a property of concurrency by which the amount of delay in servicing a request can become unbounded as a result of arbitration of contention for shared resources while still guaranteeing that the request will eventually be serviced. Hewitt argued that the actor model should provide the guarantee of service. In Dijkstra's model, although there could be an unbounded amount of time between the execution of sequential instructions on a computer, a (parallel) program that started out in a well defined state could terminate in only a bounded number of states [Dijkstra 1976]. Consequently, his model could not provide the guarantee of service. Dijkstra argued that it was impossible to implement unbounded nondeterminism.

    Hewitt argued otherwise: there is no bound that can be placed on how long it takes a computational circuit called an arbiter to settle (see metastability (electronics)).[21] Arbiters are used in computers to deal with the circumstance that computer clocks operate asynchronously with respect to input from outside, e.g., keyboard input, disk access, network input, etc. So it could take an unbounded time for a message sent to a computer to be received and in the meantime the computer could traverse an unbounded number of states.

    The actor model features unbounded nondeterminism which was captured in a mathematical model by Will Clinger using domain theory.[2] In the actor model, there is no global state.[dubious ]

    Direct communication and asynchrony[edit]

    Messages in the actor model are not necessarily buffered. This was a sharp break with previous approaches to models of concurrent computation. The lack of buffering caused a great deal of misunderstanding at the time of the development of the actor model and is still a controversial issue. Some researchers argued that the messages are buffered in the "ether" or the "environment". Also, messages in the actor model are simply sent (like packets in IP); there is no requirement for a synchronous handshake with the recipient.

    Actor creation plus addresses in messages means variable topology[edit]

    A natural development of the actor model was to allow addresses in messages. Influenced by packet switched networks [1961 and 1964], Hewitt proposed the development of a new model of concurrent computation in which communications would not have any required fields at all: they could be empty. Of course, if the sender of a communication desired a recipient to have access to addresses which the recipient did not already have, the address would have to be sent in the communication.

    For example, an actor might need to send a message to a recipient actor from which it later expects to receive a response, but the response will actually be handled by a third actor component that has been configured to receive and handle the response (for example, a different actor implementing the observer pattern). The original actor could accomplish this by sending a communication that includes the message it wishes to send, along with the address of the third actor that will handle the response. This third actor that will handle the response is called the resumption (sometimes also called a continuation or stack frame). When the recipient actor is ready to send a response, it sends the response message to the resumption actor address that was included in the original communication.

    So, the ability of actors to create new actors with which they can exchange communications, along with the ability to include the addresses of other actors in messages, gives actors the ability to create and participate in arbitrarily variable topological relationships with one another, much as the objects in Simula and other object-oriented languages may also be relationally composed into variable topologies of message-exchanging objects.

    Inherently concurrent[edit]

    As opposed to the previous approach based on composing sequential processes, the actor model was developed as an inherently concurrent model. In the actor model sequentiality was a special case that derived from concurrent computation as explained in actor model theory.

    No requirement on order of message arrival[edit]

    Hewitt argued against adding the requirement that messages must arrive in the order in which they are sent to the actor. If output message ordering is desired, then it can be modeled by a queue actor that provides this functionality. Such a queue actor would queue the messages that arrived so that they could be retrieved in FIFO order. So if an actor X sent a message M1 to an actor Y, and later X sent another message M2 to Y, there is no requirement that M1 arrives at Y before M2.

    In this respect the actor model mirrors packet switching systems which do not guarantee that packets must be received in the order sent. Not providing the order of delivery guarantee allows packet switching to buffer packets, use multiple paths to send packets, resend damaged packets, and to provide other optimizations.

    For example, actors are allowed to pipeline the processing of messages. What this means is that in the course of processing a message M1, an actor can designate the behavior to be used to process the next message, and then in fact begin processing another message M2 before it has finished processing M1. Just because an actor is allowed to pipeline the processing of messages does not mean that it must pipeline the processing. Whether a message is pipelined is an engineering tradeoff. How would an external observer know whether the processing of a message by an actor has been pipelined? There is no ambiguity in the definition of an actor created by the possibility of pipelining. Of course, it is possible to perform the pipeline optimization incorrectly in some implementations, in which case unexpected behavior may occur.

    Locality[edit]

    Another important characteristic of the actor model is locality.

    Locality means that in processing a message, an actor can send messages only to addresses that it receives in the message, addresses that it already had before it received the message, and addresses for actors that it creates while processing the message. (But see Synthesizing addresses of actors.)

    Also locality means that there is no simultaneous change in multiple locations. In this way it differs from some other models of concurrency, e.g., the Petri net model in which tokens are simultaneously removed from multiple locations and placed in other locations.

    Composing actor systems[edit]

    The idea of composing actor systems into larger ones is an important aspect of modularity that was developed in Gul Agha's doctoral dissertation,[6] developed later by Gul Agha, Ian Mason, Scott Smith, and Carolyn Talcott.[9]

    Behaviors[edit]

    A key innovation was the introduction of behavior specified as a mathematical function to express what an actor does when it processes a message, including specifying a new behavior to process the next message that arrives. Behaviors provided a mechanism to mathematically model the sharing in concurrency.

    Behaviors also freed the actor model from implementation details, e.g., the Smalltalk-72 token stream interpreter. However, it is critical to understand that the efficient implementation of systems described by the actor model require extensive optimization. See Actor model implementation for details.

    Modeling other concurrency systems[edit]

    Other concurrency systems (e.g.process calculi) can be modeled in the actor model using a two-phase commit protocol.[22]

    Computational Representation Theorem[edit]

    There is a Computational Representation Theorem in the actor model for systems which are closed in the sense that they do not receive communications from outside. The mathematical denotation denoted by a closed system {\displaystyle {\mathtt {S}}} is constructed from an initial behavior S and a behavior-approximating function progressionS. These obtain increasingly better approximations and construct a denotation (meaning) for {\displaystyle {\mathtt {S}}} as follows [Hewitt 2008; Clinger 1981]:

    {\displaystyle \mathbf {Denote} _{\mathtt {S}}\equiv \lim _{i\to \infty }\mathbf {progression} _{{\mathtt {S}}^{i}}(\bot _{\mathtt {S}})}

    In this way, S can be mathematically characterized in terms of all its possible behaviors (including those involving unbounded nondeterminism). Although {\displaystyle \mathbf {Denote} _{\mathtt {S}}} is not an implementation of {\displaystyle {\mathtt {S}}}, it can be used to prove a generalization of the Church-Turing-Rosser-Kleene thesis [Kleene 1943]:

    A consequence of the above theorem is that a finite actor can nondeterministically respond with an uncountable[clarify] number of different outputs.

    Relationship to logic programming[edit]

    One of the key motivations for the development of the actor model was to understand and deal with the control structure issues that arose in development of the Planner programming language.[citation needed] Once the actor model was initially defined, an important challenge was to understand the power of the model relative to Robert Kowalski's thesis that "computation can be subsumed by deduction". Hewitt argued that Kowalski's thesis turned out to be false for the concurrent computation in the actor model (see Indeterminacy in concurrent computation).

    Nevertheless, attempts were made to extend logic programming to concurrent computation. However, Hewitt and Agha [1991] claimed that the resulting systems were not deductive in the following sense: computational steps of the concurrent logic programming systems do not follow deductively from previous steps (see Indeterminacy in concurrent computation). Recently, logic programming has been integrated into the actor model in a way that maintains logical semantics.[21]

    Migration[edit]

    Migration in the actor model is the ability of actors to change locations. E.g., in his dissertation, Aki Yonezawa modeled a post office that customer actors could enter, change locations within while operating, and exit. An actor that can migrate can be modeled by having a location actor that changes when the actor migrates. However the faithfulness of this modeling is controversial and the subject of research.[citation needed]

    Security[edit]

    The security of actors can be protected in the following ways:

    Synthesizing addresses of actors[edit]

    A delicate point in the actor model is the ability to synthesize the address of an actor. In some cases security can be used to prevent the synthesis of addresses (see Security). However, if an actor address is simply a bit string then clearly it can be synthesized although it may be difficult or even infeasible to guess the address of an actor if the bit strings are long enough. SOAP uses a URL for the address of an endpoint where an actor can be reached. Since a URL is a character string, it can clearly be synthesized although encryption can make it virtually impossible to guess.

    Synthesizing the addresses of actors is usually modeled using mapping. The idea is to use an actor system to perform the mapping to the actual actor addresses. For example, on a computer the memory structure of the computer can be modeled as an actor system that does the mapping. In the case of SOAP addresses, it's modeling the DNS and the rest of the URL mapping.

    Contrast with other models of message-passing concurrency[edit]

    Robin Milner's initial published work on concurrency[23] was also notable in that it was not based on composing sequential processes. His work differed from the actor model because it was based on a fixed number of processes of fixed topology communicating numbers and strings using synchronous communication. The original communicating sequential processes (CSP) model[24] published by Tony Hoare differed from the actor model because it was based on the parallel composition of a fixed number of sequential processes connected in a fixed topology, and communicating using synchronous message-passing based on process names (see Actor model and process calculi history). Later versions of CSP abandoned communication based on process names in favor of anonymous communication via channels, an approach also used in Milner's work on the calculus of communicating systems and the π-calculus.

    These early models by Milner and Hoare both had the property of bounded nondeterminism. Modern, theoretical CSP ([Hoare 1985] and [Roscoe 2005]) explicitly provides unbounded nondeterminism.

    Petri nets and their extensions (e.g., coloured Petri nets) are like actors in that they are based on asynchronous message passing and unbounded nondeterminism, while they are like early CSP in that they define fixed topologies of elementary processing steps (transitions) and message repositories (places).

    Influence[edit]

    The actor model has been influential on both theory development and practical software development.

    Theory[edit]

    The actor model has influenced the development of the π-calculus and subsequent process calculi. In his Turing lecture, Robin Milner wrote:[25]

    Now, the pure lambda-calculus is built with just two kinds of thing: terms and variables. Can we achieve the same economy for a process calculus? Carl Hewitt, with his actors model, responded to this challenge long ago; he declared that a value, an operator on values, and a process should all be the same kind of thing: an actor.

    This goal impressed me, because it implies the homogeneity and completeness of expression ... But it was long before I could see how to attain the goal in terms of an algebraic calculus...

    So, in the spirit of Hewitt, our first step is to demand that all things denoted by terms or accessed by names—values, registers, operators, processes, objects—are all of the same kind of thing; they should all be processes.

    Practice[edit]

    The actor model has had extensive influence on commercial practice. For example, Twitter has used actors for scalability.[26] Also, Microsoft has used the actor model in the development of its Asynchronous Agents Library.[27] There are many other actor libraries listed in the actor libraries and frameworks section below.

    Addressed issues[edit]

    According to Hewitt [2006], the actor model addresses issues in computer and communications architecture, concurrent programming languages, and Web services including the following:

    • Scalability: the challenge of scaling up concurrency both locally and nonlocally.
    • Transparency: bridging the chasm between local and nonlocal concurrency. Transparency is currently a controversial issue. Some researchers[who?] have advocated a strict separation between local concurrency using concurrent programming languages (e.g., Java and C#) from nonlocal concurrency using SOAP for Web services. Strict separation produces a lack of transparency that causes problems when it is desirable/necessary to change between local and nonlocal access to Web services (see Distributed computing).
    • Inconsistency: inconsistency is the norm because all very large knowledge systems about human information system interactions are inconsistent. This inconsistency extends to the documentation and specifications of very large systems (e.g., Microsoft Windows software, etc.), which are internally inconsistent.

    Many of the ideas introduced in the actor model are now also finding application in multi-agent systems for these same reasons [Hewitt 2006b 2007b]. The key difference is that agent systems (in most definitions) impose extra constraints upon the actors, typically requiring that they make use of commitments and goals.

    Programming with actors[edit]

    A number of different programming languages employ the actor model or some variation of it. These languages include:

    Early actor programming languages[edit]

    Later actor programming languages[edit]

    Actor libraries and frameworks[edit]

    Actor libraries or frameworks have also been implemented to permit actor-style programming in languages that don't have actors built-in. Some of these frameworks are:

    NameStatusLatest releaseLicenseLanguages
    ReActed Active 2021-09-05 Apache 2.0 Java
    Acteur Active 2020-04-16[45] Apache-2.0 / MIT Rust
    Bastion Active 2020-08-12[46] Apache-2.0 / MIT Rust
    Actix Active 2020-09-11[47] MIT Rust
    Aojet Active 2016-10-17 MIT Swift
    Actor Active 2017-03-09 MIT Java
    Actor4j Active 2020-01-31 Apache 2.0 Java
    Actr Active 2019-04-09[48] Apache 2.0 Java
    Vert.x Active 2018-02-13 Apache 2.0 Java, Groovy, Javascript, Ruby, Scala, Kotlin, Ceylon
    ActorFx Inactive 2013-11-13 Apache 2.0 .NET
    Akka (toolkit) Active 2019-05-21[49] Apache 2.0 Java and Scala
    Akka.NET Active 2020-08-20[50] Apache 2.0 .NET
    Remact.Net Inactive 2016-06-26 MIT .NET, Javascript
    Ateji PX Inactive ? ? Java
    czmq Active 2016-11-10 MPL-2 C
    F# MailboxProcessor Active same as F# (built-in core library) Apache License F#
    Korus Active 2010-02-04 GPL 3 Java
    Kilim[51] Active 2018-11-09[52] MIT Java
    ActorFoundry (based on Kilim) Inactive 2008-12-28 ? Java
    ActorKit Active 2011-09-13[53] BSD Objective-C
    Cloud Haskell Active 2015-06-17[54] BSD Haskell
    CloudI Active 2021-05-27[55] MIT ATS, C/C++, Elixir/Erlang/LFE, Go, Haskell, Java, Javascript, OCaml, Perl, PHP, Python, Ruby
    Clutter Active 2017-05-12[56] LGPL 2.1 C, C++ (cluttermm), Python (pyclutter), Perl (perl-Clutter)
    NAct Inactive 2012-02-28 LGPL 3.0 .NET
    Nact Active 2018-06-06[57] Apache 2.0 JavaScript/ReasonML
    Retlang Inactive 2011-05-18[58] New BSD .NET
    JActor Inactive 2013-01-22 LGPL Java
    Jetlang Active 2013-05-30[59] New BSD Java
    Haskell-Actor Active? 2008 New BSD Haskell
    GPars Active 2014-05-09[60] Apache 2.0 Groovy
    OOSMOS Active 2019-05-09[61] GPL 2.0 and commercial (dual licensing) C. C++ friendly
    Panini Active 2014-05-22 MPL 1.1 Programming Language by itself
    PARLEY Active? 2007-22-07 GPL 2.1 Python
    Peernetic Active 2007-06-29 LGPL 3.0 Java
    Picos Active 2020-02-04 MIT KRL
    PostSharp Active 2014-09-24 Commercial / Freemium .NET
    Pulsar Active 2016-07-09[62] New BSD Python
    Pulsar Active 2016-02-18[63] LGPL/Eclipse Clojure
    Pykka Active 2019-05-07[64] Apache 2.0 Python
    Termite Scheme Active? 2009-05-21 LGPL Scheme (Gambit implementation)
    Theron Inactive[65] 2014-01-18[66] MIT[67] C++
    Thespian Active 2020-03-10 MIT Python
    Quasar Active 2018-11-02[68] LGPL/Eclipse Java
    Libactor Active? 2009 GPL 2.0 C
    Actor-CPP Active 2012-03-10[69] GPL 2.0 C++
    S4 Inactive 2012-07-31[70] Apache 2.0 Java
    C++ Actor Framework (CAF) Active 2020-02-08[71] Boost Software License 1.0 and BSD 3-Clause C++11
    Celluloid Active 2018-12-20[72] MIT Ruby
    LabVIEW Actor Framework Active 2012-03-01[73] National Instruments SLA LabVIEW
    LabVIEW Messenger Library Active 2021-05-24 BSD LabVIEW
    Orbit Active 2019-05-28[74] New BSD Java
    QP frameworks for real-time embedded systems Active 2019-05-25[75] GPL 2.0 and commercial (dual licensing) C and C++
    libprocess Active 2013-06-19 Apache 2.0 C++
    SObjectizer Active 2020-05-09[76] New BSD C++11
    rotor Active 2020-10-23[77] MIT License C++17
    Orleans Active 2021-09-03[78] MIT License C#/.NET
    Skynet Active 2020-12-10 MIT License C/Lua
    Reactors.IO Active 2016-06-14 BSD License Java/Scala
    libagents Active 2020-03-08 Free software license C++11
    Proto.Actor Active 2021-01-05 Free software license Go, C#, Python, JavaScript, Java, Kotlin
    FunctionalJava Active 2018-08-18[79] BSD 3-Clause Java
    Riker Active 2019-01-04 MIT License Rust
    Comedy Active 2019-03-09 EPL 1.0 JavaScript
    VLINGO XOOM Actors Active 2017-12-20 Mozilla Public License 2.0 Java, Kotlin, JVM languages, C# .NET
    wasmCloud Active 2021-03-23 Apache 2.0 WebAssembly (Rust, TinyGo, Zig, AssemblyScript)
    ray Active 2020-08-27 Apache 2.0 Python

    See also[edit]

    演员模型[编辑]

    维基百科,自由的百科全书
     
     
     
    跳到导航跳到搜索

    计算机科学中,演员模型(英语:Actor model)是一种并发运算上的模型。“演员”是一种程序上的抽象概念,被视为并发运算的基本单元:当一个演员接收到一则消息,它可以做出一些决策、创建更多的演员、发送更多的消息、决定要如何回答接下来的消息。演员可以修改它们自己的私有状态,但是只能通过消息间接的相互影响(避免了基于锁的同步)。

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

    基本概念[编辑]

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

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

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

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

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

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

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

  • 相关阅读:
    jmeter实现上传文件
    jmeter之调度器设置
    存储过程的几种传参方式
    Charles篡改数据
    软件测试职业发展方向
    最近发现一个有意思的lua游戏引擎,名字叫love2d
    2016,新的一年来到。
    Corona手游教程之widget:Slider篇
    Corona手游教程之widget:PickerWheel篇
    Corona手游教程之widget:ProgressView篇
  • 原文地址:https://www.cnblogs.com/rsapaper/p/15573556.html
Copyright © 2020-2023  润新知