Actors 是一种异步编程模式,它的提出主要是为了解决 “多线程,MTA” 编程带来的复杂性、困难度。

但这些都不是 Actors 本身提供的最大优点,它真正的价值是易于解决多线程处理,容易导致共享资源(share resources)之间产生竞争,故而导致 deadlock(死锁)。

一个软件工程项目里面并非所有的开发人员都经历过严格的 “多核编程” 数年摧残,纵然受过多年毒打的开发人员有时也容易写出 deadlock(死锁)的疑难问题,往往经验及技术越强的人搞出死锁就越难解决。

设计模式及编程模型,提出目的都是为了让代码写起来更简单、更易于阅读、后期工程维护,但不意味着设计模式及编程模型的应用会让代码执行的效率更高,或许是更低也说不一定。

有时候不要过于注重形式,没有意义,可以解决人们迫切问题的设计模式及编程模型才是有价值与意义的,个人多年经验之谈。

Actors 基于消息驱动的异步编程模型,本文在标题上就已经明确提出了 Actors 异步编程模型的核心要点:“基于消息驱动”

每个线程可以运行一个或多个 Actors 消息驱动器,有些类似 Windows 窗体编程中的消息队列(WndProc),当某个消息到达,人们对感兴趣的消息逐个进行处理。

Actors 异步编程模型里面要求,所有的线程或进程之间都通过消息的方式进行合作,所以采用 Actors 异步编程模型的结构大约如下图所示:

上图为简化的理解图,Actors 是一个消息生产 + 消费的驱动模型,设A与B两个端点,A为生产Actors Action,B为消费处理 Actors Action 端点

A与B之间传递消息(Actor Action)的传输层介质,可以是进程内存、共享内存、Socket套接字、Pipe 匿名/命名管道,Actor 本身不限制消息传递的介质层。

Actors 模型本身不解决传输介质层出现故障而导致的 Actor Actions 消息丢失的问题,例如:A节点生产一个消息经Socket套接字推送到B节点,但Socket套接字发生故障导致该生产的消息被丢失。

如何解决此问题?对于异步编程而言,一些行为并不需要ACK确认已经处理该消息,但如果确定需要对方处理该消息,则需要实现一种名为 “停等ARQ”【停等超时自动重传】ACK确认的机制以确保消息被传递到目标节点上被处理,但这属于传输介质层设计时需要考虑的东西,与 Actors 模型并没有任何关系。

所以,人们从此处不需要参考 Actors 更多博客/书籍/文献就可以自行推导出,Actors 从设计之初就是为了解决多线程编程的一些问题,而不是为了分布式而设计的,只是发展到分布式的时代仍然有大量的解决方案工程采用 Actors 异步编程编程模型而已。

那么什么是本文提出的 “Actors Action”?

比如A节点向B节点 Publish(生产)一个 Actor Action,那么它至少携带以下信息:

1、Action ID(动作ID)

2、进阶:Sequence ID(序列ID)用于ACK确认,注意:它与 Actor 模型本身无关

3、Action 载荷的数据模型(贫血模型)

4、Origin(来源信息若不需要应答则不需要)

B节点从消息队列中 Peek 弹出顶部入列消息(FIFO先入先出原则),调度派发器则基于 Action ID 来派发消息到对应的 Actor Action Handler(Actor 动作处理器)来消费处理该动作的行为。

那么 Action 载荷的数据模型,如何在调度派发器内解决呢?

很容易:

C# 工程语言可以编写工程内消息模型的序列化算法,根据ID来映射对应的 “贫血数据模型”,管理的方法有两种:

1、基于反射检索元数据的方式来自动构建及建立映射,例如在数据模型头上声明特性,静态标记:Action ID。

2、手动注册 Action ID 跟数据模型的映射关系

C/C++ 工程语言可以编写工程内消息模型的静态序列化算法,如采用静态编译的序列化 google protobuf,解决方案仍是手动注册 Action ID 跟数据模型之间的映射关系。

当我们为 Action 增加进阶的序列ID,那么则可以实现 “停等ARQ” 的机制,那么也为RPC远过程调用的实现提供可能性,如果我们在 C/C++ 语言中,最好实现的编程模型为APM(异步编程模型)

例如:

修改玩家状态

参考一:ChangePlayerStatusAsync( args..., lambda... )

参考二:BeginChangePlayerStatus( args...., [...](args...) {

auto result = EndChangePlayerStatus(...);

// TO:DO Your are code here.

})

但当我们在 Actors 异步编程模型的基础上,增加了RPC远过程调用,那么则可能带来一个全新的潜在问题,“deadlock” 逻辑层的死锁,如:A远过程调用B,B远过程调用A,调用上下层级关系不明确,或许大多数开发人员皆曾犯过该错误。

注意:此类错误跟 Actors 异步编程模式并没有直接关系,将其归纳于 Actors 异步编程模式本身的缺点,理解上有问题的。

Actors 异步编程模型总结:

重点(一):

Actors 异步编程模式,本身是没有多线程下的安全问题的,原因很明显,它是只是把消息生产并推送到消息消费者的消息队列,这个过程甚至不需要加锁(临界区)

这取决于底层传输媒介,若同个进程内存传递的需要上锁,消息队列本身并非必是线程安全,例如:C/C++ 工程语言常常适用STL标准库中的 std::queue、std::list 泛型模板BCL基础类库。

重点(二):

Actors 异步编程模式,本身不提供停等ARQ,消息确认机制,因为实现类似的机制导致的逻辑死锁是开发人员的问题,不是 Actors 模式本身的缺点,扣锅还是的要点脸,没有的东西不要给别人加头上。

重点(三):

Actors 异步编程模式,是最初是用于解决并缓解 “单进程多线程” 内共享资源(share-resource)竞争导致的死锁、内存安全、多核编程编码复杂度的问题。

例如:

A线程访问共享资源竞争锁,B线程访问共享资源竞争到锁,但A线程访问另外一个共享资源竞争到锁,B线程尝试访问另外一个共享资源竞争锁,那么就会发生相互竞争死锁现象。

当人采用:

Actors 模式时,我们将该共享资源按需要自行划分挂在到一个具体的 Actors 调度器负责驱动处理,当其它线程/进程需要访问该共享资源时,交付请求到目的 Actors 调度器上负责的 Actors Action Handler 进行处理,那么操作该共享的资源都在单个工作线程上,所以不需要额外的增加互斥锁。

Actors 模型系统执行非常高效,但其效能表现仍无法比拟多线程内存之间相互访问的效率,但并非绝对的,某些情况下 Actors 模型系统的效能表现优于多线程模型的系统,当然不说大家也明白不是,这么对比没有意义。

重点(四):

Actors 异步编程模式,基于消息驱动,势必会带来大量碎片化的消息报文数据,这必定造成严重内存碎片问题,致内存分配的效率下跌,C/C++ 开发人员应注意对内存碎片问题进行优化处理,由更先进的 “现代工业高级编程语言” 特性来解决,个人建议人们适用:“Microsoft C# by dotNET.”

C/C++ 可以采用以下几类解决方案:

1、定长/对齐数据报文,尽量避免随机颗粒化分配

2、分配固定大小区块,划分若干个小区块,每个小区块缓存一个消息

3、自行实现碎片整理(移动内存)

4、适用开源内存池,掩耳盗铃把问题丢向内存池(例:jemalloc)

重点(五):

Actors 异步编程模式驱动的执行单元是一个线程(线程是程序执行最小单元),如果单个线程负载过多性能会成为瓶颈的,但这并不算 Actors 模式本身的缺点,如果需要承担的负载过重,开发人员应当思考如何优化并解决

例如:更加细化的拆分非本职业务到其它的 Actors 的驱动器/线程进行负责,而不是说这就是 Actors 模式本身的缺点,这不是一个好的解决问题的态度。

如果学过 “领域驱动模型” 的童靴们,应该很明白大多数某个具体 Actors 产生性能瓶颈,均是上层模型领域职责过于宽泛,负责的事务远远超出它本身应当承担的事务导致的,但凡是不是绝对的,对多数软件工程项目而言,它却是问题的本质原因。

是的为每个模块/接口的粒度划分存在一些问题,就像人们在进行多线程(多核)编程时,需要注重锁(lock)的粒度问题,如果人们粒度太大那么多线程系统的效率可能还不如单线程的效能,如果粒度太小,编程复杂性就会直线提高,因为通常锁粒度应用越小越容易遇到死锁的问题,但相对的代码效能通常就越高(指综合并发效能指数,对硬件负载及利用率越高)。

Actors 基于消息驱动的异步编程模型相关推荐

  1. 【转】异步编程:.NET 4.5 基于任务的异步编程模型(TAP)

    最近我为大家陆续介绍了"IAsyncResult异步编程模型 (APM)"和"基于事件的异步编程模式(EAP)"两种异步编程模型.在.NET4.0 中Micro ...

  2. 【转】1.8异步编程:.NET 4.5 基于任务的异步编程模型(TAP)

    传送门:异步编程系列目录-- 最近我为大家陆续介绍了"IAsyncResult异步编程模型 (APM)"和"基于事件的异步编程模式(EAP)"两种异步编程模型. ...

  3. 【转】1.6异步编程:IAsyncResult异步编程模型 (APM)

    传送门:异步编程系列目录-- 大部分开发人员,在开发多线程应用程序时,都是使用ThreadPool的QueueUserWorkItem方法来发起一次简单的异步操作.然而,这个技术存在许多限制.最大的问 ...

  4. 异步编程模型--使用 IAsyncResult 对象

    先推荐阅读下面的资料: MSDN:异步编程设计模式 IBM developerworks: 使用异步 I/O 大大提高应用程序的性能 参考博文: 1.正确使用异步操作 2.Lab:体会ASP.NET异 ...

  5. c# 三种异步编程模型EAP(*)、 APM(*)和 TPL

    为什么80%的码农都做不了架构师?>>>    EAP 是 Event-based Asynchronous Pattern(基于事件的异步模型)的简写 优点是简单,缺点是当实现复杂 ...

  6. [你必须知道的异步编程]——异步编程模型(APM)

    本专题概要: 引言 你知道APM吗? 你想知道如何使用异步编程模型编写代码吗? 使用委托也可以实现异步编程,你知道否? 小结 一.引言 在前面的C#基础知识系列中介绍了从C#1.0--C#4.0中一些 ...

  7. 【转】谈谈c#中异步编程模型的变迁**

    大家在编程过程中都会用到一些异步编程的情况.在c#的BCL中,很多api都提供了异步方法,初学者可能对各种不同异步方法的使用感到迷惑,本文主要为大家梳理一下异步方法的变迁以及如何使用异步方法. Beg ...

  8. C#异步编程-------异步编程模型(APM)

    术语解释: APM               异步编程模型, Asynchronous Programming Model EAP                基于事件的异步编程模式, Event ...

  9. 异步编程模型(C#5.0系列)

    关于C#5.0的新功能--async和await关键字.它们是语法糖,可以简化异步操作代码的构造.当C#编译器看到一个await表达式时,它会生成代码,该代码自动异步地调用该表达式,然后立即将控制流返 ...

  10. 简单地使用线程之一:使用异步编程模型

    .NetFramework的异步编程模型从本质上来说是使用线程池来完成异步的任务,异步委托.HttpWebRequest等都使用了异步模型. 这里我们使用异步委托来说明异步编程模型. 首先,我们来明确 ...

最新文章

  1. RS485通信如何设计EMC电路?
  2. 深入理解数据结构之链表
  3. appium ios 真机自动化环境搭建
  4. MIT Molecular Biology 笔记5 转录机制
  5. getdate()函数的用法.`
  6. Linux学习记录-----《快乐的Linux命令行》.
  7. CodeForces - 2B The least round way
  8. 登录服务器修改数据库吗,如何修改服务器登录数据库 sa
  9. leetcode179. 最大数
  10. mysql的socket文件_修改socket文件, MySQL启动报错
  11. js 点击闭包_【JS进阶】Javascript 闭包与Promise的碰撞
  12. L3-016 二叉搜索树的结构 (30 分)-PAT 团体程序设计天梯赛 GPLT
  13. 区块链学习笔记(二)
  14. CAN详解--各家CAN分析仪与软件的比较
  15. 友华pt622g说明书_友华通信电信光猫 双口光纤猫PT622 这个可以设置无线吗
  16. CSS 小技巧:如何保留 hover 的状态?
  17. sinc函数原型滤波器窗口matlab,sinc函数
  18. GPIO(通用输入/输出接口)
  19. 自学Java day12 使用jvav实现链表 从jvav到架构师
  20. 混合波束成形|重叠子阵结构下的HBF探讨

热门文章

  1. 建站选择Linux还是Windows操作系统?
  2. 【新手案例】Python3.7如何获取网络时间
  3. 2021-07-26 SEO优化_关键词密度设置算法
  4. 阿里如何做好双11技术保障?大队长霜波分享4点经验
  5. Windows系统申请苹果证书
  6. 研究了四大计算机名校的培养方案,核心课程都在这了
  7. tp801单板微型计算机英文全称,TP801型微型计算机在低压铸造与差压铸造液面加压控制系统中的应用.pdf...
  8. Flickr网站架构分析
  9. 房地产开发建设项目管理(全程房地产典范企业案例)
  10. 计算机系统还原后 桌面不显示图标,电脑桌面图标不见了怎么恢复原状?电脑桌面便签不见了怎么找回...