标签:保护 and 资源 并发编程 其他 put ++ create 请求
这一章是全书的核心,也是后续章节的总览。在这一章中,我们按照服务器程序的一般原理, 将服务器结构为如下三个主要模块:
I/O处理单元。本章将介绍I/O处理单元的四种I/O模型和两种高效时间处理模式。
逻辑单元。本章将介绍逻辑单元的两种高效并发模式,以及高效的逻辑处理方式----有限状态机。
存储单元。本书不讨论存储单元,因为它只是服务器程序的可选模块,而且其内容与网络编程本身无关。
最后,本章还介绍了提高服务器性能的其他建议。
TCP服务器和TCP客户端的工作流程(图)
C/S模型非常适合资源相对几重的场合,并且它的实现也很简单,但其缺点也很明显: 服务器是通信的中心,当访问量过大时,可能所有客户端都将得到很慢的响应。
P2P模型使得每台机器在消耗服务的同事也给别人提供服务,这样自由能够充分、自由地共享。 P2P模型的缺点也很明显:当用户之间传输的请求过多时,网络的负载将加重。
P2P模型还存在一个显著的问题,即主机之间很难互相发现。所以实际使用的P2P模型通常带有一个专门的发现服务器。 这个发现服务器通常还提供查找服务,使每个客户都能尽快地找到自己需要的资源。
I/O 处理单元
请求队列
逻辑单元
请求队列
网络存储单元(可选)
I/O 处理单元是服务器管理客户连接的模块。
一个逻辑单元通常是一个进程或线程。
网络存储单元可以是数据库、缓存和文件。
请求队列是个单元之间的通信方式的抽象。
阻塞 I/O
I/O 复用
SIGIO 信号
异步 I/O
服务器通常要处理3类事件:I/O事件、信号及定时事件。
Reactor是这样一种模式,它要求主线程(I/O处理单元,下同)只负责监听文件描述上是否有事件发生, 有的话就立即将该事件通知工作线程(逻辑单元,下同)。除此之外,主线程不做任何其他实质性的工作。 读写数据,接收新的连接,以及处理客户端请求均在工作线程中完成。
Proactor模式将所有I/O操作都交给主线程和内核来处理,工作线程仅仅负责业务逻辑。
从实现上来说,并发编程主要有多进程和多线程两种方式。
并发模式是指I/O处理单元和多个逻辑单元之间协调完成任务的方法。
服务器主要有两种并发编程模式:
在I/O模型中,“同步”和“异步”区分的是内核向应用程序通知的是何种I/O事件(是就绪事件还是完成事件), 以及该由谁来完成I/O读写(是应用程序还是内核)
在并发模式中,“同步”指的是程序完全按照代码序列的顺序指向;“异步”指的是程序的执行需要由系统事件来驱动。 常见的系统事件包括中断、信号等。
半同步/半异步模式中,同步线程用于处理客户逻辑,异步线程用于处理I/O事件。
领导者/追随者模式是多个工作线程轮流获得事件源集合,轮流监听、分发并处理事件的一种模式。 在任意时间点,程序都仅有一个领导者线程,它负责监听I/O事件。 而其他线程则都是追随者,它们休眠在线程池中等待成为新的领导者。 当前领导者如果检测到I/O事件,首先要从线程池中推选出新的领导者线程,然后处理I/O事件。 此时新的领导者等待新的I/O事件,而原来的领导者则处理I/O事件,二者实现了并发。
领导者/追随者模式包含如下几个组件:
前面两节探讨的是服务器的I/O处理单元、请求队列和逻辑单元之间协调完成任务的各种模式, 这一节我们介绍逻辑单元内部的一种高效编程方法:有限状态机(finite state machine)
// code:8.1 STATE_MACHINE( Package _pack ) { PackageType _type = _pack.GetType(); switch( _type ) { case type_A: process_package_A( _pack ); break; case type_B: process_package_B( _pack ); break; } } // code:8.2 STATE_MACHINE() { State cur_State = type_A; while( cur_State != type_C ) { Package _pack = getNewPackage(); switch( cur_State ) { case type_A: process_package_state_A( _pack ); cur_State = type_B; break; case type_B: process_package_state_B( _pack ); cur_State = type_C; break; } } }
根据不同的资源类型,池可分为很多种,常见的有内存池、进程池、线程池和连接池。
高性能服务器应该避免不必要的数据复制,尤其是当数据复制发生在用户代码和内核之间的时候。
并发程序必须考虑上下文切换(context switch)的问题,即进程切换或线程切换导致的系统开销。
并发程序需要考虑的另外一个问题是共享资源的枷锁保护。锁通常被认为是导致服务器效率低下的一个因素, 因为由它引入的代码不仅不处理任何业务逻辑,而且需要访问内核资源。 如果必须使用“锁”,则可以考虑减小锁的粒度。
这里只是整理大概内容,更详细内容,请看书??《Linux高性能服务器编程》 游双 著,机械工业出版社]
标签:保护 and 资源 并发编程 其他 put ++ create 请求
原文地址:https://www.cnblogs.com/music-liang/p/11922408.html