上节我们对于两种事件处理模式做了简要的分析,在这里我们对于两种高效的并发编程方式来进行简单讨论,后序会继续完善
半同步/半异步方式
- 对于并发编程中的“同步"和"异步"是与I/O模型中的"同步"和"异步"是两种不同的概念
- 并发模式中,"同步"指的是程序完全按照代码序列的形式来执行的
-"异步"执行需要由系统事件来进行驱动
然而两种方法各有优缺点,异步线程虽然执行效率高,实施性很强,但是相对复杂,难以调控和扩展,同步虽然效率底下但是逻辑简单,我们可以将两者结合起来来进行实现
在半同步/半异步的模式中,同步线程用于处理客户逻辑,异步线程用于处理I/O事件,在这里我们拿服务器程序中的一种变体(半同步/半异步反应堆模式)来进行说明
异步线程只负责监听所有socket上的事件,在epoll内核事件表中注册该socket的事件,当有任务到来时后,工作队列上的线程将被唤醒,通过竞争来获得任务的管理权
-一般来说半同步/半异步反应堆采用的事件处理模式是Reactor模式:它要求工作线程自己从socket上读取客户请求和往socket写入服务器应答,同时也可以使用模拟的Proactor事件处理模式,由主线程来完成数据的读写,主线程将任务类型,数据等封装为一个任务对象,然后将其插入请求队列,工作线程从请求队列之中取得任务后将其处理.
半同步/半异步堆模式缺点
- 主线程和工作线程共享请求队列.主线程往请求队列中添加任务,或者工作线程从请求队列中取出任务,都需要对请求队列加锁保护,不然会造成线程竞争
- 每个工作线程在同一个事件中只能处理一个客户请求
领导者/追随者模式
领导者/追随者模式是多个工作线程轮流获得事件源集和,轮流监听,分发并且处理事件的一种模式
- 在任意时间点,程序都仅仅只有一个领导者线程,它负责监听I/O事件。
- 其他线程都是追随者,它们休眠在线程池中等待成为心得领导者.
- 领导者如果检测到了I/O事件,先推选出新的领导者,然后处理I/O事件
领导者/追随者模式包括:句柄集,线程集,事件处理器和具体的事务处理器.
1.句柄集
句柄用于表示I/O资源,在Linux系统上一般是文件描述符.句柄集管理众多句柄,使用wait_for_event方法来进行监听,并将就绪的事件通知给领导者线程,领导者则通过绑定句柄上的事件处理器来进行处理事件,领导者将句柄和事件处理器绑定是通过调用句柄中的方法事件
2.线程集
这个组件是所有工作线程(包括领导者线程和追随者线程)的管理者.负责各线程之间的同步,以及新领导者的推先.线程集中的线程在任一时间必处于三种状态之一:
- Leader,线程处于领导者身份,负责等待I/O时间
- Processing,线程正在处理事件.领导者检测到I/O事件之后,可以转此状态来处理事件,推选新的领导者,也可以指定其他追随者来处理事件,此时领导者的地位不变
- Follower,线程处于追随者状态,可以通过调用线程集的join方法等待成为心得领导者
推选新的领导者和追随者等待成新领导者都需要避免竟态条件
3.事件处理器和具体的事件处理器
- 事件处理器通常包括一个或者多个回调函数,这些回调函数用于处理事件对应的业务i逻辑。事件处理器在使用前需要被绑定到某个句柄值上。具体的事件处理器就是在事件处理器的派生类,必须重新实现基类的方法,处理特定的任务
缺点:只支持一个事件源的集和