当前位置: 首页 > article >正文

一步一步写线程之六数据通信并发模型Actor和CSP

一、多线程间的数据通信

前面的线程模型基本分析完成了,现在回到一个老的问题即多线(进)程间的数组通信是怎么实现的?在前面的分析中可以知道有很多种方式:Socket、事件、消息、文件和管道等等。而且在通信过程中也有互斥体、临界区、信号灯等的控制,可这个数据通信是不是也可以抽象得生成模型来描述一下呢?答案当然是肯定的,而且这玩意儿老早就有大牛给出答案了。

二、通信模型(CSP and Actor)

通信模型主要有两种,即CSP和Actor,下面就分别对其进行分析说明。
1、CSP并发模型
CSP(Communicating Sequential Processes)并发模型是在1978年由计算机科学家Tony Hoare提出。其核心的思想是通过在独立执行的进程之间进行通信来实现并发。那这样就引出一个问题,线(进)程间独立干活是很美好的,但它们之间不互相勾搭了么?那多线程编程的意义何在?
既然大牛提出了这个模型,当然会给出解决的方式,其实就有点类似前面的半同步半异步中的队列,多个独立的线程可以从一个公共的管道(Channel)中读取(或写入)任务或者数据。但是,这种执行的过程却不象多线程一样是抢占的而是按顺序的串行执行的。
那么问题来了,并发为什么又串行?可以从两个角度来理解这个问题:
首先,可以尽量拆分成细粒度的执行单元,按照一定的顺序执行,达到减少并发同步的可能(如果需要同步则并行就无法进行了);其次,使用更高层次的方式,比如协程,一个线程内的协程本身是串行的(即多个线程中的协程仍然是并行的,仍然可以理解成多线程),但协程运行的底层线程是并行的。
其实这样就好理解了,CSP其实更适合一些IO密集型的应用(当然需要多线程+协程),因为这种场景下,IO收发过程并发同步很少且当前IO阻塞时可以切换到其它IO中继续工作。有没有点觉得和啥相象?对,就是异步IO+回调处理,可是这个写起来就复杂多了。
虽然这个技术提出的很早,但真正为广大程序员所接受,正是Golang语言的出现,才让其在编程界被广泛认知。不过Go语言中的CSP机制里面的任务增加了缓冲机制与传统的CSP略有一些不同。

2、Actor并发模型
Actor并发模型在1973年由Carl Hewitt提出。即由一种处理并发和分布式系统的抽象方法。它通过划分成的独立实体即Actor,在其之间通过消息进行通信。Actor模型的可以简化并发编程实现避免共享状态和显式锁的方法。这个技术应用即使到现在估计仍然有相当多的程序员不了解甚至没听说过,它一般在一些小众语言或者游戏开发后端编程中应用较多。需要注意的是,主流语言基本都不支持这种方式,需要自己手撕代码。
Actor模型中,每个Actor最多只能做一样工作,且可拥有自己的状态及变量数据,它通过类似于邮箱的机制来实现数据交互,比较常见的就是大家熟悉的发布订阅机制。有过akka库应用的应该还是熟悉这其中的道理的。
那么,结论出来了,这种模型,基本就是分布式的那一套,自己处理自己的,不影响别人,别人也不影响自己,大家只对邮箱的消息负责,完美实现了设计原则中的最小职责和解耦的目的。

三、二者比较

既然这两者都适用于数据通信,那么二者有何区别呢:
1、CSP强调的是传送的通道,并不关心是谁发谁收(匿名方式);而Actor强调的自身而非消息发送的方式(方式可以有很多种),即通信收发双方是有明确的地址的(这有点类似于网络通信)
2、Actor通过MailBox(邮箱盒子)来传送消息,消息基本都是异步的;而CSP使用Channel(通道)来传送消息,一般是同步(当然也可以处理成异步,比如GO中)
3、同步意味着可以立刻工作,异步意味着工作很可能不会立刻工作
4、Actor的并发是容易理解的而CSP的并发需要理解再理解一下
5、CSP强调线程间的协同,而Actor则强调独立工作
6、CSP更类似于多线程编程;Actor有点面向对象的意思
7、CSP只能通过Channel传递消息;Actor可以连续的调用Actor传递消息

四、总结

数据通信模型和多线程编程本身是密不可分的,原则上来讲,谈及多线程编程一般就是要实现多线程之间的通信,否则多线程技术本身并没有什么可讨论的。一个技术其实如何能真得可以深入掌握进去,其实就是一个生态,围绕着它或近或远或紧密或间疏的有着各种各样的其它技术与之互相配合。挨过来一样,在其它的技术上,可能学习的这个技术又是其生态中的一环。明白了吧,你中有我,我中有你,这才最终形成了更广义上的计算机技术。
单纯的希望学习某一项技术解决问题,其实是一种缘木求鱼的心态,学习要包容并蓄,但又要在有限的时间内确定重点,有取有舍。
这篇其实主要是拓展视野,略微有些务虚。本来想写几个Go或者Akka的例子,但觉得实在是没有啥特别大的借鉴意义。Go的协程会用的自然明白怎么回事,不会用的,其它语言现在基本没有协程(如C++的协程还得等等),说半天仍然是不知所云;而Actor中典型的Scala语言用得更是少之又少,专业性强于模型本身。所以先掌握好理论,等待有机会再实际上手实践吧。


http://www.kler.cn/a/228781.html

相关文章:

  • 基于springboot的口腔管理平台
  • 聚铭网络6款产品入选CCIA《网络安全专用产品指南》
  • Crewai + langchain 框架配置第三方(非原生/国产)大模型API
  • ESP8266-01S、手机、STM32连接
  • Python与PyTorch的浅拷贝与深拷贝
  • 【SPIE出版|EI、Scopus双检索】2025年绿色能源与环境系统国际学术会议(GEES 2025)
  • 代码随想录算法训练营DAY13 | 栈与队列 (3)
  • Matlab:利用1D-CNN(一维卷积神经网络),分析高光谱曲线数据或时序数据
  • 从编程中理解:大脑的成瘾行为
  • 神经网络激活函数到底是什么?
  • Log360,引入全新安全与风险管理功能,助力企业积极抵御网络威胁
  • 前端的事件代理
  • 【C++】I/O多路转接详解(二)
  • ReactNative实现弧形拖动条
  • 十年炒股心得
  • UI自动化中元素无法定位问题解决方法
  • @ResponseBody
  • idea中找到所有的TODO
  • 【计算机网络】物理层概述|通信基础|奈氏准则|香农定理|信道复用技术
  • 使用PHPStudy搭建本地web网站并实现任意浏览器公网访问
  • 第八届:世界3D渲染挑战赛《无尽阶梯》正式开启
  • QT 的 blockSignals(true) 的作用范围
  • error: failed to push some refs to....
  • 基于Vue2用keydown、setTimeout事件实现连续按键(连击)任意键(或组合键)3秒触发自定义事件(以F1键为例)
  • 分享62个节日PPT,总有一款适合您
  • 2024最新最详细【接口测试总结】