socket server的N种并发模型

模型⼀、单线程Accept(⽆IO复⽤)

模型分析:

① 主线程main thread执⾏阻塞Accept,每次客户端Connect链接过来,main thread中accept响应并建⽴连接

② 创建链接成功,得到Connfd1套接字后, 依然在main thread串⾏处理套接字读写,并处理业务。

③ 在②处理业务中,如果有新客户端Connect过来,Server⽆响应,直到当前套接字全部业务处理完毕。

④ 当前客户端处理完后,完毕链接,处理下⼀个客户端请求。

优缺点:

优点 socket编程流程清晰且简单,适合学习使⽤,了解socket基本编程流程。

缺点 该模型并⾮并发模型,是串⾏的服务器,同⼀时刻,监听并响应最⼤的⽹络请求量为1。 即并发量为1。 仅适合学习基本socket编程,不适合任何服务器Server构建

模型⼆、单线程Accept+多线程读写业务(⽆IO复⽤)

模型分析:

① 主线程main thread执⾏阻塞Accept,每次客户端Connect链接过来,main thread中accept响应并建⽴连接

② 创建链接成功,得到Connfd1套接字后,创建⼀个新线程thread1⽤来处理客户端的读写业务。main thead依然回到 Accept阻塞等待新客户端。

③ thread1通过套接字Connfd1与客户端进⾏通信读写。

④ server在②处理业务中,如果有新客户端Connect过来,main thread中Accept依然响应并建⽴连接,重复②过程。

优缺点

优点

基于模型⼀: ⽀持了并发的特性 使⽤笔记灵活,⼀个客户端对应⼀个线程单独处理,server处理业务的内聚性⽐较⾼,客户端⽆ 论如何写、服务端均会有⼀个线程做资源响应。

缺点

随着客户端的数量增多,需要开辟的线程的数量也增加, 客户端和server线程的数量1:1正 ⽐关系。因此对于⾼并发场景,线程数量受到硬件的瓶颈。线程过多也会增加CPU的切换成 本,降低CPU的利⽤率。 对于⻓链接,客户端⼀旦⽆业务读写,只要不关闭,server就应该对保持这个链接的状态(⼼ 跳检测,健康检查机制), 占⽤连接资源和线程的开销 仅适合客户端数量不⼤,并且是可控的场景来使⽤ 适合学习基本的socket编程,不适合做并发服务器

模型三、单线程多路IO复⽤

模型分析

① 主线程main thread创建listenFd之后,采⽤多路I/O复⽤机制(如:select、epoll)进⾏IO状态阻塞监控。有Client1客户端Connect请求,I/O 复⽤机制检测到ListenFd触发读事件,则进⾏Accept建⽴连接,并将新⽣成的connFd1加⼊到监听I/O集合中。

② Client1再次进⾏正常读写业务请求,main thread的多路I/O复⽤机制阻塞返回,会触该套接字的读/写事件等。

③ 对于Client1的读写业务,Server依然在main thread执⾏流程提继续执⾏,此时如果有新的客户端Connect链接请求过 来,Server将没有即时响应。

④ 等到Server处理完⼀个连接的Read+Write操作,继续回到多路I/O复⽤机制阻塞,其他链接过来重复 ②、③流程。

优缺点

优点

单流程体解决了可以同时监听多个客户端读写状态的模型,不需要1:1客户端的线程数量关系 多路I/O复⽤,阻塞,⾮忙轮询状态,不浪费CPU资源,对CPU利⽤率较⾼

缺点

虽然可以监听多个客户端读写状态,但是同⼀时间内,只能够处理⼀个客户端的读写操作,实际上读写业务并发为1 当多个客户端访问server, 业务是串⾏执⾏,⼤量请求的会有排队延迟的现象。⽐如Client3占据main thread流程时, client1和client2流程会卡在IO复⽤等待下次监听触发事件。

模型四、单线程多路IO复⽤+多线程读写业务(业务⼯作池)

模型分析

① 主线程main thread创建listenFd之后,采⽤多路I/O复⽤机制(如:select、epoll)进⾏IO状态阻塞监控。有Client1客 户端Connect请求,I/O复⽤机制检测到ListenFd触发读事件,则进⾏Accept建⽴连接,并将新⽣成的connFd1加⼊到 监听I/O集合中。

② 当connFd1有可读消息,触发读事件,并且进⾏读写消息

③ main thread按照固定的协议读取消息,并且交给worker pool⼯作线程池, ⼯作线程池在server启动 之前就已经开启固定数量的thread,⾥⾯的线程只处理消息业务,不进⾏套接字读写操作。

④ ⼯作池处理完业务,触发connFd1写事件,将回执客户端的消息通过main thead写给对⽅。

优缺点

优点

对于模型三,将业务的处理部分,通过⼯作池分离出来。能够减少客户端访问Server导致业务串⾏执 ⾏会有⼤量请求拍短的延迟时间。 实际上读写的业务并发为1,但是业务流程的并发为worker pool线程数量,加快了业务处理的并⾏效率。

缺点

读写依然是main thread单独处理,最⾼的读写并⾏通道依然为1 虽然多个worker线程处理业务,但是最后返回给客户端依旧也需要排队。因为出⼝还是main thraed的read+write 1 个通道

模型五、单线程IO复⽤+多线程IO复⽤(链接线程池)

模型分析

① Server在启动监听之前,开辟固定数量(N)的线程,⽤Thead Pool线程池管理

② 主线程main thread创建listenFd之后,采⽤多路I/O复⽤机制(如:select、epoll)进⾏IO状态阻塞监控。有Client1客户端 Connect请求,I/O复⽤机制检测到ListenFd触发读事件,则进⾏Accept建⽴连接,并将新⽣成的connFd1分发给Thread Pool中 的某个线程进⾏监听。

③ Thread Pool中的每个thread都启动多路I/O复⽤机制(select、epoll),⽤来监听main thread建⽴成功并且分发下来的socket套 接字。

④ 如图, thread监听ConnFd1、ConnFd2, thread2监听ConnFd3,thread3监听ConnFd4. 当对应的ConnFd有读写事 件,对应的线程处理该套接字的读写及业务。

优缺点

优点

将之前main thread单流程的读写(模型三),分散到多线程类完成,这样就增加了同⼀时刻读写的并⾏通道,并⾏ 通道的数量N,N就是线程池线程的数量

server同时监听的ConnFd套接字的数量,⼏乎是成倍增加, 之前的全部的监控数量取决于main thread的多路IO复⽤ 机制的最⼤限制(select 1024, epoll默认与内存⼤⼩有关,约3~6W不等),所以理论单点Server最⾼响应并发数量 N*(3~6W)(N是线程池的线程数量,建议线程的数量与CPU核⼼的数量⽐例是1:1)

如果良好的线程池数量和CPU核⼼数适配,那么可以尝试CPU核⼼与Thread进⾏绑定,从⽽降低CPU的切换频率,提升每 个Thread处理合理业务的效率,降低CPU的切换成本

缺点

虽然监听的并发数量提升,但是最⾼的读写并⾏通道依然为N,并且多个身处于同⼀个Thread的客户端,会出现读写延迟 现象。实际上每个Thread模型特征与模型三:单线程多路IO复⽤机制是⼀致的。

模型五(进程版)、单进程多路I/O复⽤+多进程多路I/O复⽤(进程池)

模型分析

与模型五、单线程IO复⽤+多线程IO复⽤(链接线程池)⽆⼤差异。

不同点

进程和线程的内存布局不同导致,main process(主进程)不再进⾏Accept操作,⽽是将Accept过程 分散到各个⼦进程(process)中.

进程的特性,资源独⽴,所以main process如果Accept成功的fd,其他进程⽆法共享资源,所以需 要各⼦进程⾃⾏Accept创建链接

main process只是监听ListenFd状态,⼀旦触发读事件(有新连接请求). 通过⼀些IPC(进程间通信:如信 号、共享内存、管道)等, 让各⾃⼦进程Process竞争Accept完成链接建⽴,并各⾃监听。

优缺点

与模型五、单线程IO复⽤+多线程IO复⽤(链接线程池)⽆⼤差异。

不同点 多进程内存资源空间占⽤稍微⼤⼀些 多进程模型安全稳定型较强,这也是因为各⾃进程互不⼲扰的特点导致。

模型六、单线程多路I/O复⽤+多线程多路I/O复⽤+多线程

模型分析

① Server在启动监听之前,开辟固定数量(N)的线程,⽤Thead Pool线程池管理

② 主线程main thread创建listenFd之后,采⽤多路I/O复⽤机制(如:select、epoll)进⾏IO状态阻塞监控。有Client1客户端Connect请求,I/O复⽤机 制检测到ListenFd触发读事件,则进⾏Accept建⽴连接,并将新⽣成的connFd1分发给Thread Pool中的某个线程进⾏监听。

③ Thread Pool中的每个thread都启动多路I/O复⽤机制(select、epoll),⽤来监听main thread建⽴成功并且分发下来的socket套接字。⼀旦其中 某个被监听的客户端套接字触发I/O读写事件,那么,会⽴刻开辟⼀个新线程来处理I/O读写业务。

④ 当某个读写线程完成当前读写业务,如果当前套接字没有被关闭,那么将当前客户端套接字如:ConnFd3重新加回线程池的监控线程中,同时 ⾃身线程⾃我销毁。

优缺点

优点

在模型五基础上,除了能够保证同时响应最⾼的并发数,⼜能够解决读写并⾏通道的局限问题 同⼀时刻的读写并⾏通道,达到了最⼤化极限, ⼀个客户端可以对应⼀个单独的执⾏流程处理读写业务,读写并⾏通道与客户端的数量1:1关系

缺点

该模型过于理想化,以为要求CPU核⼼数数量⾜够⼤ 如果硬件CPU数量可数,那么该模型就造成⼤量的CPU切换的成本浪费。因为为了保证读写并⾏通道和客户 端是1:1的关系,就要保证server开辟的thread的数量与客户端⼀致。

原文地址:https://www.cnblogs.com/peteremperor/p/13727205.html