服务器两种高效的并发模式

来源:互联网 发布:网络写作平台推荐 编辑:程序博客网 时间:2024/05/19 23:11

1.概念

并发目的:让程序“同时”执行多个任务。

  • 如果程序是计算密集型,并发编程没有优势,反而由于任务的切换使效率降低;
  • 如果是I/O密集型,比如经常读写文件,访问数据库,则并发编程优势很高,因为I/O操作的速度远没有CPU的计算速度快,所以程序阻塞与I/O操作将浪费大量的CPU时间。

2.实现方式

并发实现方式:主要有多线程和多进程两种方式;并发模式是指I/O单元和多个逻辑单元协调完成任务的方法。

3.服务器两种并发模式

1.半同步/半异步模式

  • 半同步/半异步模式和I/O同步/,异步是两个概念,I/O模型中,“同步”和“异步”区分的是内核向应用程序通知的是何种I/O事件(就绪时间还是完成事件),以及该由谁来完成I/O读写(是应用程序还是内核)。
  • 并发模式中,“同步”指的是程序完全按照代码序列的顺序执行;“异步”指的是程序的执行需要由系统事件来驱动。常见的系统事件有:中断,信号等。


  • 半同步/半异步模式中:同步线程处理客户逻辑,相当于逻辑单元;异步线程用于处理I/O事件,相当于I/O处理单元。异步线程监听到客户请求后,就将其封装成对象并插入请求队列中,请求队列通知某个工作在同步模式的工作线程来读取并处理该请求对象。请求队列的设计主要有:轮流选取工作线程的Round Robin算法,通过条件变量或信号量随机选择一个工作线程。



2.领导者/追随者模式

  • 该模式是多个工作线程轮流获得事件源的集合,轮流监听,分发并处理事件的一种模式。
  • 在任意时间点,程序有且仅有一个领导者线程,它负责监听I/O事件,而且他线程则都是追随者,他们休眠在线程池中等待成为新的领导者。
  • 当前领导者检测到I/O事件,首先要从线程池中推选出新的领导者线程,处理I/O事件,此时,新的领导者等待新的I/O事件,而原来的领导者则处理I/O事件,二者实现了并发。
  • 领导者/追随者模式包含如下几个组件:句柄集(HandleSet),线程集(ThreadSet),事件处理器(EventHandler),具体的事件处理器(ConcreteEventHandler)。


  • 句柄集(HandleSet)
    用于表示I/O资源,在Linux下通常就是一个文件描述符。句柄集管理众多句柄,它使用wait_for_event方法监听这些句柄上的I/O事件,并将其中的就绪事件通知给领导者线程。领导者则调用绑定到Handle上的事件处理器来处理事件。领导者将Handle和事件处理器绑定是同通过调用句柄集中的register_handle方法是实现的。
  • 线程集(ThreadSet)
    这个组件是所有工作线程(包括领导者线程和追随者线程)的管理者。负责各线程之间的同步以及新的领导者线程的推选。线程集中的线程在任意时间必处于三种状态之一:
     1.Leader:线程当前处于领导者身份,负责等待监听句柄集上的I/O事件。
     2.Processing:线程正在处理事件,领导者检测到I/O事件之后,可以转移到Processing状态来处理该事件,并调用promote_new_leader方法推选新的领导者;也可以指定其他追随者来处理时间(Event Handoff),此时领导者的地位不变;当处于Processing状态的线程处理完事件之后,如果当前线程没有领导者,则它将成为新的领导者,否则它将直接转变为追随者。
    3.Follower:线程当前处于追随者身份,通过调用join方法等待成为新的领导者,也可能被当前领导者指定来处理新的任务。
    需要注意:领导者线程推选新的领导者和追随者等待成为新的领导者这两个操作都将修改线程集,因此,线程集提供一个成员Synchronizer来同步这两个操作,避免竞态条件。


  • 事件处理器和具体事件处理器
    1.事件处理器通常包含一个或多个回调函数handle_event。这些回调函数用于处理事件对应的业务逻辑。事件处理器在使用前需要绑定到某个句柄上,当该句柄上有事件发生时,领导者就执行与之绑定的事件处理器中的回调函数。
    2.具体的事件处理器:是事件处理器的派生类。它们必须重新实现基类的handle_event方法,以处理特定的任务。


  • 由于领导者线程自己监听I/O事件并处理客户请求,因而领导者/追随者模式不需要在线程之间传递任何额外的数据,也无需像半同步/半反应堆模式那样在线程之间同步对应请求队列的访问。但是领导者/追随者的明显缺点:仅支持一个事件源集合,因此无法让让每个线程独立地管理多个客户连接。
















原创粉丝点击