Actor的原理

2023-05-16

http://www.cnblogs.com/netfocus/p/3365166.html

先从著名的c10k问题谈起。有一个叫Dan Kegel的人在网上(http://www.kegel.com/c10k.html)提出:现在的硬件应该能够让一台机器支持10000个并发的client。然后他讨论了用不同的方式实现大规模并发服务的技术,归纳起来就是两种方式:一个client一个thread,用blocking I/O;多个clients一个thread,用nonblocking I/O或者asynchronous I/O。目前asynchronous I/O的支持在Linux上还不是很好,所以一般都是用nonblocking I/O。大多数的实现都是用epoll()的edge triggering(传统的select()有很大的性能问题)。这就引出了thread和event之争,因为前者就是完全用线程来处理并发,后者是用事件驱动来处理并发。当然实际的系统当中往往是混合系统:用事件驱动来处理网络时间,而用线程来处理事务。由于目前操作系统(尤其是Linux)和程序语言的限制(Java/C/C++等),线程无法实现大规模的并发事务。一般的机器,要保证性能的话,线程数量基本要限制几百(Linux上的线程有个特点,就是达到一定数量以后,会导致系统性能指数下降,参看SEDA的论文)。所以现在很多高性能web server都是使用事件驱动机制,比如nginx,Tornado,node.js等等。事件驱动几乎成了高并发的同义词,一时间红的不得了。

其实线程和事件,或者说同步和异步之争早就在学术领域争了几十年了。1978年有人为了平息争论,写了论文证明了用线性的process(线程的模式)和消息传递(事件的模式)是等价的,而且如果实现合适,两者应该有同等性能。当然这是理论上的。针对事件驱动的流行,2003年加大伯克利发表了一篇论文叫“Why events are a bad idea (for high-concurrency servers)”,指出其实事件驱动并没有在功能上有比线程有什么优越之处,但编程要麻烦很多,而且特别容易出错。线程的问题,无非是目前的实现的原因。一个是线程占的资源太大,一创建就分配几个MB的stack,一般的机器能支持的线程大受限制。针对这点,可以用自动扩展的stack,创建的先少分点,然后动态增加。第二个是线程的切换负担太大,Linux中实际上process和thread是一回事,区别就在于是否共享地址空间。解决这个问题的办法是用轻量级的线程实现,通过合作式的办法来实现共享系统的线程。这样一个是切换的花费很少,另外一个可以维护比较小的stack。他们用coroutine和nonblocking I/O(用的是poll()+thread pool)实现了一个原型系统,证明了性能并不比事件驱动差。

那是不是说明线程只要实现的好就行了呢。也不完全对。2006年还是加大伯克利,发表了一篇论文叫“The problem with threads”。线程也不行。原因是这样的。目前的程序的模型基本上是基于顺序执行。顺序执行是确定性的,容易保证正确性。而人的思维方式也往往是单线程的。线程的模式是强行在单线程,顺序执行的基础上加入了并发和不确定性。这样程序的正确性就很难保证。线程之间的同步是通过共享内存来实现的,你很难来对并发线程和共享内存来建立数学模型,其中有很大的不确定性,而不确定性是编程的巨大敌人。作者以他们的一个项目中的经验来说明,保证多线程的程序的正确性,几乎是不可能的事情。首先,很多很简单的模式,在多线程的情况下,要保证正确性,需要注意很多非常微妙的细节,否则就会导致deadlock或者race condition。其次,由于人的思维的限制,即使你采取各种消除不确定的办法,比如monitor,transactional memory,还有promise/future,等等机制,还是很难保证面面俱到。以作者的项目为例,他们有计算机科学的专家,有最聪明的研究生,采用了整套软件工程的流程:design review, code review, regression tests, automated code coverage metrics,认为已经消除了大多数问题,不过还是在系统运行4年以后,出现了一个deadlock。作者说,很多多线程的程序实际上存在并发错误,只不过由于硬件的并行度不够,往往不显示出来。随着硬件的并行度越来越高,很多原来运行完好的程序,很可能会发生问题。我自己的体会也是,程序NPE,core dump都不怕,最怕的就是race condition和deadlock,因为这些都是不确定的(non-deterministic),往往很难重现。

那既然线程+共享内存不行,什么样的模型可以帮我们解决并发计算的问题呢。研究领域已经发展了一些模型,目前越来越多地开始被新的程序语言采用。最主要的一个就是Actor模型。它的主要思想就是用一些并发的实体,称为actor,他们之间的通过发送消息来同步。所谓“Don’t communicate by sharing memory, share memory by communicating”。Actor模型和线程的共享内存机制是等价的。实际上,Actor模型一般通过底层的thread/lock/buffer 等机制来实现,是高层的机制。Actor模型是数学上的模型,有理论的支持。另一个类似的数学模型是CSP(communicating sequential process)。早期的实现这些理论的语言最著名的就是erlang和occam。尤其是erlang,所谓的Ericsson Language,目的就是实现大规模的并发程序,用于电信系统。Erlang后来成为比较流行的语言。

类似Actor/CSP的消息传递机制。Go语言中也提供了这样的功能。Go的并发实体叫做goroutine,类似coroutine,但不需要自己调度。Runtime自己就会把goroutine调度到系统的线程上去运行,多个goroutine共享一个线程。如果有一个要阻塞,系统就会自动把其他的goroutine调度到其他的线程上去。


一些名词定义:Processes, threads, green threads, protothreads, fibers, coroutines: what's the difference?

  1. Process: OS-managed (possibly) truly concurrent, at least in the presence of suitable hardware support. Exist within their own address space.
  2. Thread: OS-managed, within the same address space as the parent and all its other threads. Possibly truly concurrent, and multi-tasking is pre-emptive.
  3. Green Thread: These are user-space projections of the same concept as threads, but are not OS-managed. Probably not truly concurrent, except in the sense that there may be multiple worker threads or processes giving them CPU time concurrently, so probably best to consider this as interleaved or multiplexed.
  4. Protothreads: I couldn't really tease a definition out of these. I think they are interleaved and program-managed, but don't take my word for it. My sense was that they are essentially an application-specific implementation of the same kind of "green threads" model, with appropriate modification for the application domain.
  5. Fibers: OS-managed. Exactly threads, except co-operatively multitasking, and hence not truly concurrent.
  6. Coroutines: Exactly fibers, except not OS-managed.Coroutines are computer program components that generalize subroutines to allow multiple entry points for suspending and resuming execution at certain locations. Coroutines are well-suited for implementing more familiar program components such as cooperative tasks, iterators, infinite lists and pipes.Continuation: An abstract representation of the control state of a computer program.A continuation reifies the program control state, i.e. the continuationis a data structure that represents the computational process at a given point in the process' execution; the created data structure can be accessed by the programming language, instead of being hidden in the runtime environment. Continuations are useful for encoding other control mechanisms in programming languages such as exceptions, generators, coroutines, and so on.
  7. The "current continuation" or "continuation of the computation step" is the continuation that, from the perspective of running code, would be derived from the current point in a program's execution. The term continuations can also be used to refer to first-class continuations, which are constructs that give a programming language the ability to save the execution state at any pointand return to that point at a later point in the program.(yield keywork in some languages, such as c# or python)
  8. Goroutines: They claim to be unlike anything else, but they seem to be exactly green threads, as in, process-managed in a single address space and multiplexed onto system threads. Perhaps somebody with more knowledge of Go can cut through the marketing material.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Actor的原理 的相关文章

  • 获取现有的或创建新的 akka actor

    我正在尝试使用 ActorFor 获取现有的 ActorRef 或创建一个新的 ActorRef 如果它不存在 我有以下代码 但它似乎没有按预期工作 isTermminate 始终为 true ActorSystem system Acto
  • 如何在 Scala Actor 模型中重载 bang(!) 运算符?

    在 Scala 的 Actor 模型实现中 我们可以重写 bang 运算符吗 我们可以通过重载这个操作符来修改消息传递的操作吗 示例场景 当任何参与者调用另一个参与者时 我需要包括信息记录 演员通过传递消息 因此 通过重载消息传递 运算符
  • 如何在 Java 应用程序中使用 Akka Actors?

    我想用阿卡演员在爪哇 我下载了akka 1 0 zip并添加了akka actor 1 0 jar到我在 Eclipse 中的 构建路径 然后我写了这个 Actor 类 package com example import akka act
  • libGdx 如何使用图像或演员作为主体

    我浏览了 libGdx wiki 教程 但没有找到使用图像或演员作为物理体的示例 在我的游戏中 我在舞台上添加了一名演员 但我想添加这个演员或精灵图像作为物理体 我必须拖动这个演员 甚至想要检测与其他物体的碰撞 如果有请给我参考 Thank
  • LMAX 的颠覆者模式如何运作?

    我正在尝试理解破坏者模式 我观看了 InfoQ 视频并尝试阅读他们的论文 我知道涉及一个环形缓冲区 它被初始化为一个非常大的数组 以利用缓存局部性 消除新内存的分配 听起来好像有一个或多个原子整数来跟踪位置 每个 事件 似乎都有一个唯一的
  • 跟踪 Erlang 中从邮箱消费消息的操作

    我浏览了文档trace 3Erlang 中的 BIF 然而 我的一个观察结果是它不能用于跟踪邮箱中消息的使用情况 旗帜 receive 仅跟踪消息何时添加到进程的邮箱 有没有一种方法可以跟踪事件 例如使用receive构造 如果不是 是否有
  • 您如何向非程序员解释演员? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 好吧 标题差不多就是这样 如果我让一个非技术人员 我的妈妈 12 岁的男孩 可卡犬坐在你面前并要求你解释actors http en
  • 把jdbc操作放在actor中好不好?

    我正在构建一个传统的 Web 应用程序 通过 JDBC 执行数据库 CRUD 操作 我想知道将 jdbc 操作放入当前请求处理线程之外的参与者中是否合适 我做了一些搜索 但没有找到演示此功能的教程或示例应用程序 那么有哪些缺点和优点呢 这种
  • TPL 数据流和 Akka.net 有什么区别?

    我曾使用过 TPL 数据流 真的很喜欢它 我从我的 java scala 朋友那里多次听到 Akka 这个词 所以我尝试阅读相关内容 发现 akka 也有一个 net 端口 伟大的 当我继续阅读 akka 是什么时 我惊讶地发现它听起来和
  • 如何在单个服务中托管多个 Service Fabric Actor 类型?

    我读了here https azure microsoft com en gb documentation articles service fabric reliable actors platform 应该可以在同一服务中托管紧密耦合的
  • Scala Actors:如果 React 永远不会返回,为什么它需要循环{},为什么 while(true) 不起作用?

    刚刚开始使用 Scala Actors 这斯卡拉网站 http www scala lang org node 242 says 可以通过使用来避免线程阻塞操作react等待 新消息 基于事件的挂件receive 然而 有一个 通常很小 支
  • RemoteActor 取消注册 actor

    我正在玩 RemoteActors 现在我想知道 如果我关闭 RemoteActor 会发生什么 该 Actor 可通过 RemoteActor alive 和 RemoteActor register 来使用 我找不到两者的逆 活着和注册
  • Akka设计原则

    在开发一个相当大的 Akka 应用程序时 我在使用普通方法和非 Akka 类时遇到了一个非常简单的结构 但在使用 Akka 时实际上很难确定 这就是为什么我来这里问你什么建议是解决此问题的最佳方法 所以问题是这样的 我有一个父角色 我们称他
  • 将 ActorRef 传递给其他 Actor 是好是坏?

    我想弄清楚我是否使用传递 AkkaActorRef围绕其他参与者并不是一种反模式 我的系统中有一些演员 有些寿命很长 restClientRouter publisher 有些人在完成工作后就死了 geoActor 短命参与者需要向长命参与
  • 持久 Akka 邮箱和无损

    在 Akka 中 当一个 actor 在处理消息时死亡 内部onReceive 该消息丢失 有没有办法保证无损 有没有办法配置 Akka 始终保留消息before将他们发送到onReceive 以便在演员死亡时可以恢复并重播 也许像持久邮箱
  • 无法反序列化 ActorRef 以将结果发送到不同的 Actor

    我开始使用 Spark Streaming 来处理我收到的实时数据源 我的场景是 我有一个使用 with ActorHelper 的 Akka actor 接收器 然后我让 Spark 作业执行一些映射和转换 然后我想将结果发送给另一个 a
  • Akka 的语言和产品替代品是什么?

    现在我正在看游戏框架 https www playframework com 并且非常喜欢它 Play 中提供的功能中最受宣传的部分之一是Akka http akka io 为了更好地理解 Akka 以及如何正确使用它 您能告诉我其他语言或
  • Akka Actor 询问和类型安全

    我如何使用 Akka Actor Ask 并维护类型安全 或者避免使用 询问 而使用 告诉 打电话时 or ask在 Akka Actor 上 Future Any 返回 我必须通过进行显式转换future mapTo MyType 我不喜
  • Akka 和 ReactiveMongo

    我正在尝试找到在集群工作人员之间共享相同连接池的最佳方法 我有以下结构 Master Actor gt Worker Actors 最多 100 个或更多 gt MongoDB 我想在工作人员和 MongoDB 之间放置reactivemo
  • 演员邮箱溢出。斯卡拉

    我目前正在与 scala 的两位演员合作 一 producer 产生一些数据并将其发送到parcer 生产者发送一个HashMap String HashMap Object List Int 通过消息 以及this标记发件人 parcer

随机推荐

  • 《OpenCV-Python初学者疑难问题集》专栏目录

    本专栏为免费专栏 https blog csdn net LaoYuanPython article details 109160152 OpenCV Python图形图像处理专栏 的伴生付费专栏 xff0c 用于发布一些学习OpenCV
  • 使用Python+Moviepy 5行代码实现两视频顺序拼接

    老猿Python博文目录 xff1a https blog csdn net LaoYuanPython 一 引言 最近看到好几篇类似 n行Python代码 的博文 xff0c 看起来还挺不错 xff0c 简洁 实用 xff0c 传播了知识
  • 图像滤波基础知识:图像与波的关系以及图像噪声知识

    前往老猿Python博文目录 https blog csdn net LaoYuanPython 一 引言 老猿对图像处理基础知识非常缺乏 xff0c 所以OpenCV Python的学习进度很慢 xff0c 很多基础概念和原理的东西花了大
  • 用Python通过摄像头进行视频录制

    老猿Python博文目录 xff1a https blog csdn net LaoYuanPython 用Python通过摄像头进行视频录制 一 引言 要实现摄像头录播摄像信息 xff0c 通过Python有很多种实现方式 xff0c 老
  • 计算机四级网络工程师——操作系统部分题目笔记汇总【1~10题】

    计算机四级笔记 操作系统部分 xff1a xff08 1 10题 xff09 因篇幅过长 xff0c 为保证学习质量 xff0c 遂将其分成四部分 xff08 四篇博客 xff09 每10题为一篇 xff0c 其他题目在我的计算机四级考试网
  • 一文带你读懂PyQt:用Python做出与C++一样的GUI界面应用程序

    一 简介 Python标准库更多的适合处理后台任务 xff0c 唯一的图形库tkinter使用起来很不方便 xff0c 所以后来出现了针对Python图形界面开发的扩展库 xff0c 今天老猿要介绍的是主流Python图形界面扩展库之一的P
  • Python中可迭代对象是什么?

    Python中可迭代对象 Iterable 并不是指某种具体的数据类型 xff0c 它是指存储了元素的一个容器对象 xff0c 且容器中的元素可以通过 iter 方法或 getitem 方法访问 iter 方法的作用是让对象可以用for i
  • 老猿Python博客文章目录索引

    本目录提供老猿Python所有相关博文的一级目录汇总 xff0c 带星号的为付费专栏 xff1a 一 专栏列表 本部分为老猿所有专栏的列表 xff0c 每个专栏都有该专栏置顶的博文目录 xff1a Python基础教程目录PyQt入门学习
  • 用TAP方式让QEMU虚拟机与host联网

    转载自 cgjvcd 最终编辑 cgjvcd QEMU虚拟机网络的缺省模式是NAT方式 xff0c 即虚拟机可以通过host访问外网 xff0c 但host和外网无法访问虚拟机 如果要想让host访问虚拟机 xff0c 则可以使用TAP方式
  • TCP服务器端怎么判断客户端已经关闭了连接?

    http xidianzhangjun blog 163 com blog static 11548877120114411056939 哎 xff0c 首先 xff0c 又犯了一个大错 xff0c 前几天把这个问题通过实验搞懂了 xff0
  • PDP上下文和PDP地址

    http www mscbsc com 10037062 viewspace 61117 html S要接入外部PDN MS还应具有与该PDN相应的地址 称为PDP地址 PDP地址是用于外部分组数据网识别MS的PDP上下文时使用的地址 如用
  • Nmap从探测到漏洞利用备忘录

    http www freebuf com articles network 32302 html 在侦查期间 xff0c 扫描一直是信息收集的初始阶段 什么是侦查 侦查是尽可能多收集关于目标网络的信息 从黑客的角度来看 xff0c 信息收集
  • 内存分配器dlmalloc 2.8.3源码浅析

    目 录 1 本文档介绍 1 2 xff0e 边界标记法 2 3 分箱式内存管理 6 4 核心结构体malloc state 13 5 内存分配相关函数 16 5 1 函数dlmalloc 16 5 2 函数tmalloc small 25
  • C++环境下的expect远程命令执行

    首先 xff0c 必须安装几个开发包 xff0c 在centos fedora下 xff0c 可以使用yum安装 yum y install tcl devel expect devel 装完以后 xff0c 就可以使用expect来写代码
  • aufs 存储机制

    aufs存储机制已经发展到超出了改进squid磁盘I O响应时间的最初尝试 34 a 34 代表着异步I O 默认的ufs和aufs之间的唯一区别 xff0c 在于I O是否被squid主进程执行 数据格式都是一样的 xff0c 所以你能在
  • align-items 与 align-content 的区别

    最明显的区别是align content 适用于多行 xff0c align item 则是适用于单行 align content xff08 单行无效 xff09 可以设置上对齐 下对齐 居中 拉伸 平分剩余空间 xff1b align
  • Apache Traffic Server 简介

    http blog sina com cn s blog 502c8cc40100mw7n html 作者 xff1a 王柯龙 一 介绍 Apache Traffic Server xff08 ATS 或 TS xff09 是一个高 性能
  • 反向代理原理

    局域网主机联入互联网的一种方式 xff0c 使用代理上网可以节约紧缺的IP地址资源 xff0c 而且可以阻断外部主机对内部主机的访问 xff0c 使内部网主机免受外部网主机的攻击 但是 xff0c 如果想让互联网上的主机访问内部网的主机资源
  • SQLite 揭秘

    http msdn microsoft com zh cn magazine ff898405 aspx 孜孜不倦的程序员 SQLite 揭秘 Ted Neward 下载示例代码 为了与本刊主题保持一致 xff0c 现在应该回过头来介绍一下
  • Actor的原理

    http www cnblogs com netfocus p 3365166 html 先从著名的c10k问题谈起 有一个叫Dan Kegel的人在网上 xff08 http www kegel com c10k html xff09 提