跟我学代码架构设计模式之--从操作系统到应用层面看如何高并发

一、应用层使用操作系统层面的多线程来做高并发

通过线程和定时器实现任务切换。

本源思想是每个线程执行一个业务代码

1 业务代码阻塞的时候业务代码主动让出CPU

2 通过硬件定时器中断CPU,强制剥夺线程的CPU执行权

缺点:

应用程序使用这种方式来高并发必须要开N多个线程,虽然通过业务让出CPU执行并没有浪费CPU时间,但是操作系统层面每个线程都维护了一个线程上下文:

首先,每个线程上下文都要占用内存空间

其次,如果操作系统中的线程过多,大部分的CPU无用功都浪费在了线程上下文切换上面了,效率很低

所以,采用扩展线程数量来做业务高并发不是一种“可伸缩”的好模型。

二、应用层的特殊设计来做高并发

通过上面的分析,我们知道,采用操作系统层面的多线程并不是一个好模型,那么有没有好的模型呢?解决方案如下:

方案1:单线程多路复用,多个线程做水平伸缩

基本思想就是开少量的线程,每个线程都可以执行多个业务代码的业务片段。

这要求每个业务片段代码都不能有阻塞,因为只有一个线程在执行多个业务代码,如果某个业务片段阻塞了线程,那么其他的业务代码都将不能继续执行。

但是,我们的业务不可能没有等待的(比如请求—响应的等待),那么我们如何设计业务代码来规避业务上的等待阻塞线程呢?这就需要我们用异步的思想来设计业务代码了:

1 把我们的业务代码拆分成多个业务代码片段,每个片段的代码中都不能阻塞线程的执行,比如http请求和响应的这种业务,可以把请求发送设计成一个代码片段,把接收响应设计成另一个代码片段。

2 通过一个片段触发另一个片段的形式来实现“业务等待”语义,比如发送请求是一个片段,接收响应是一个代码片段,处理响应一个片段,线程先执行发送片段,然后多次执行接收响应片段,响应到达后接收响应片段触发处理响应片段,

即:通过“事件”来耦合多个片段,达到如“请求-响应”这种“业务等待”的时序需求。

方案2:协程

方案1中需要我们仔细设计业务片段来做业务拆分,代码中的体现就是通过多次的回调来完成业务,对编程人员的开发和代码阅读都有一定的要求,如果能使用传统多线程编程用的顺序形式的代码来实现每个业务逻辑,同样又能在单线程中达到多个业务的多路复用就完美了,这就是协程的思想:

1 提供协程相关API,业务代码调用相关API的时候可以放弃当前业务的执行,这样单线程就去选择其他业务代码去执行了。

2 业务代码不用拆分成片段,仍采用同步形式的代码编程,代码中需要等待的时候,调用协程API来让单线程执行其他业务代码。

总结: 方案二和方案一其实本质思想都是一致的,都是单线程多路复用来达到高并发和无锁化!区别就是方案1的业务代码必须设计为异步形式的,多个业务片段完成同一个业务。

(完)

发布了63 篇原创文章 · 获赞 25 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/w1857518575/article/details/86063069
今日推荐