并发模式快瞥

声明: 所写均为个人阅读所思所想,请批判阅读。


下面的各个模型,按并发对象粒度递减,按抽象层次递增

多进程

多线程模式,最“古老”的并发模型,依赖于操作系统进程,Nginx、Apache均为多进程并发模型。

多线程

多线程模式,多进程模式的改进。线程相对于进程,在资源占用开销上更廉价。也是目前最普遍采用的并发应用模式。

进程/线程间通信方式:

  1. 共享内存
  2. 信号量
  3. 管道
  4. 内存映射
  5. 消息队列
  6. 套接字(socket)

多进程与多线程:

  1. 进程开销大,线程开销小
  2. 多线程容易引入共享变量状态问题
  3. 多线程由于共享(同一)进程的内存资源,存在上下文切换开销
  4. 进程的隔离性较线程更好
  5. 多线程程序启动时间通常较少,这在某些环境下比较敏感

多线程程序中,线程的异常处理(资源,共享变量等等)需要仔细考虑,否则极易导致整个程序崩溃;而相比线程,子进程崩溃后,通常对其他进程的影响有限,其所占用的资源等会被OS回收,因此,多进程对于应用程序稳定性更友好。

个人经验,由于过多的进程/线程均会导致系统整体性能下降,因此,通常而言,对于并发应用而言,进程/线程的并发数目都存在阈值,这通常通过对象池技术解决。

关于两种模式的编码难度和选择问题,主要考虑如下几个方面:

  1. 团队成员的背景,通常c/c++背景的coder更倾向于多进程模式,而java/c#背景的coder更倾向于多线程模式。
  2. 稳定性要求极高的场景更倾向与多进程。比如反向代理,负载均衡等等。

Corouting(CSP)

多协(纤)程模型,可以简单的理解为用户空间(相对于OS内核空间)的多“线程”。协程特点:

目前主流的语言中,都有(第三方)协程库支持,一些后续的语言也将协程在语言机制层面实现了,比如Go,Lua(5.0+)。

Go语言是个非常值得关注的语言,个人对其在并发服务器领域的前景十分看好。目前也进行了初步学习。

Actor

Actor模型其实是对传统OOP编程对象的强化:万物都是Actor,Actor对象间通信的唯一方法就是“投递异步消息”,每个对象都有一个信箱。

特点

  • 天然的分布式(多物理节点)
  • 高容错性
  • 统一的对象通信方式

同步(方法调用)变为异步(消息传递),同时解耦调用者调用操作

在Carl Hewitt关于Actor论文中,并不要求Actor是依赖于操作系统线程或进程的,Actor甚至可以通过硬件实现。Actor模型中的消息是和发送者解耦的,消息本身的时序并不被保证,因此,需要尽量保证操作的交换性。

Actor与Corouting: Actor模型的抽象层次更高,可以通过Corouting实现Actor。另外,目前主流的Corouting方案均不支持分布式Corouting,而Actor模型天然具有分布式特性。

Akka是目前Java平台最为成熟的Actor框架,就个人之见,随着系统分布式需求的普遍性,Spring将来应该也会开发与自身契合的Actor体系。