Actor 模型思想总结
Actor 模型思想总结
一句话总结:Actor 模型将计算系统理解为一个"社会"——无数独立行动者通过消息传递协作,没有共享内存,没有中央控制,这从根本上消除了并发编程中锁与竞态的复杂性。
流程图
内容梳理
一、历史演进:并发模型的六代更迭
我对 Actor 模型的理解,必须放在并发编程的历史演进中才能看清它的位置:
- 第一代:单进程阻塞 — 一次只能服务一个连接,
accept()阻塞后什么也做不了 - 第二代:fork 多进程 — 每个连接 fork 一个子进程,内存隔离但 IPC(Inter-Process Communication - 进程间通信)困难,fork 开销大,撑不住高并发
- 第三代:pthread 多线程 — 用线程代替进程,共享内存、通信方便,但引入了锁和竞态条件,随着系统膨胀,锁的管理成为噩梦
- 第四代:epoll 事件驱动 — 单线程非阻塞 I/O,一个事件循环处理所有连接,解决了锁的问题,但把业务逻辑撕成了碎片化的回调(回调地狱),没法用
if/else/while写连续逻辑 - 第五代:Lua 协程 — 利用
setjmp/longjmp在用户态切换执行上下文,实现"同步写法 + 异步执行",解决了回调地狱问题 - 第六代:Actor 模型 + 协程 = Skynet — 在协程之上加上 Actor 模型的隔离原则,每个 Actor 有独立的 Lua 虚拟机(
lua_State),只通过消息通信,既没有锁问题,又能热更新、故障隔离
二、Actor 模型的三条规矩
Actor 模型的核心是三条简单规则,它们的共同目标是消除"共享":
- 每个 Actor 有且只有自己的私有状态 — 变量不共享,没有锁的必要。对应 Skynet 中每个 Service 有独立的
lua_State,全局变量互不可见 - 通信只能靠发消息 — 消息携带的是数据拷贝而非指针,接收方改拷贝不影响发送方。对应
skynet.send()(异步)和skynet.call()(同步) - 收到消息后只能做三件事 — 修改自己的私有状态、创建新的 Actor、给其他 Actor 发消息。不能读别人的状态,想知道就发消息问
三、为什么叫"Actor":Carl Hewitt 的哲学根基
“Act”(行动)这个命名不是随意取的,背后有三层隐喻:
语言学隐喻 — “说话本身就是行动”:
Hewitt 受哲学家 John Austin 的言语行为理论(Speech Act Theory)启发。Austin 认为语言不只是描述世界,更是在改变世界——老板说"你被开除了",这句话本身就是一次改变世界状态的行为。Hewitt 将此引入计算模型:Actor 发出的每一条消息,不只是传递数据,而是一次行动,改变接收方的后续行为。
物理学隐喻 — “没有全局现在”:
Hewitt 从广义相对论借了一个直觉:相对论中没有绝对的全局参考系,信息传递有速度上限。对应到计算系统:不应该假设全局时钟和全局状态。从量子力学又借了一个直觉:观察行为会干扰系统——你无法在不影响计算的情况下窥视 Actor 内部的调度。
社会学隐喻 — “计算是一个社会,不是一台机器”:
这是最核心的隐喻。图灵机模型描述的是一颗孤立的大脑在思考,但真实世界的分布式系统——互联网服务、公司组织、生态系统——是无数独立个体在持续互动。每个个体有自己的知识(私有状态),通过语言交流(消息传递),自己决定如何回应(自主调度)。
四、Carl Hewitt 的核心思想与后期争议
Hewitt 思想的演变可以分为两个阶段:
早期(1970s-1980s,公认的奠基性贡献):
- 1973 年发表 Actor 模型原始论文,导师为 Seymour Papert 和 Marvin Minsky("Society of Mind"提出者)
- Actor 模型影响了 Scheme(Sussman 和 Steele 发现 Actor 创建操作和 lambda 是等价的)、Erlang、以及 Robin Milner 的 π 演算(Milner 的图灵奖演讲中明确感谢了 Hewitt)
后期(2000s 以后,争议越来越大):
- 提出"Inconsistency Robustness"(不一致鲁棒性):大型分布式系统的信息天然矛盾,经典逻辑的反证法推理在真实系统中是一个"bug"
- 声称 Actor 模型表达能力强于图灵机(存在 Actor 能表达的不可计算函数,非确定性图灵机表达不了),被理论计算机科学界广泛拒绝
- 在 Wikipedia 上反复修改词条引发仲裁和封禁,被 arXiv 封禁
我的判断:Hewitt 早期的直觉是深刻且正确的(分布式系统需要无共享架构、消息传递是唯一正确抽象),但他的野心远超了自己的证明能力。工程实践中被验证的是 Actor 作为并发系统组织原则这一层,而不是那些形而上的声称。
五、从思想到工程:Skynet 中 Actor 的落地
在我正在学习的 openUBMC 项目中,Actor 模型的具体体现是:
- 每个
.lua文件不是一个"脚本",而是一个 Service(即一个 Actor) skynet.start()向 C 层运行时注册回调,C 层的事件循环(epoll + 消息队列)永不退出skynet.send()对应"Actor 间发消息"——异步通知,不等待回复skynet.call()+skynet.ret()构成同步请求-回复模式——调用方协程挂起,接收方处理完回复skynet.dispatch()注册消息处理器——“收到消息后自己决定怎么处理”skynet.fork()启动新的协程处理并发任务——同一个 Service 内可以有多个协程"并行"执行- 每个 Service 崩溃不影响其他 Service——天然的故障隔离
总结与展望
总结
- Actor 模型用"不共享"替代了"用锁保护共享",从根本上消灭了死锁和竞态
- "计算是社会而非机器"这一隐喻,是理解分布式系统最有力的思维框架
- Skynet 将 Actor 实现为独立
lua_State+ 消息队列,是工程上验证过的成熟方案 - Hewitt 的物理/语言学灵感给了 Actor 模型哲学深度,但工程实践只需取其架构原则
展望/趋势
- 现代大规模分布式系统(微服务、Kubernetes 编排、Serverless)本质上都在践行 Actor 模型的三条规矩,只是换了名字
- Erlang/OTP 的
gen_server、Akka(Scala/Java)、Orleans(.NET)都是 Actor 模型的同类实现,对比学习有助于理解各实现的取舍 - Actor 模型在边缘计算和 IoT 场景有天然优势——设备天然是物理隔离的,消息传递是唯一通信方式
- 建议后续在 Skynet 实战中,刻意体会"消息驱动"和"共享内存驱动"两种思维的差异——这比记住 API 更重要
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)