`
iunknown
  • 浏览: 409246 次
社区版块
存档分类
最新评论

half-sync/half-async 和 Leader/Followers 模式的主要区别

阅读更多
《POSA2》 一书中,关于这两个模式有两个很形象的比喻:

半同步/半异步(half-sync/half-async):
许多餐厅使用 半同步/半异步 模式的变体。例如,餐厅常常雇佣一个领班负责迎接顾客,并在餐厅繁忙时留意给顾客安排桌位,为等待就餐的顾客按序排队是必要的。领班由所有顾客“共享”,不能被任何特定顾客占用太多时间。当顾客在一张桌子入坐后,有一个侍应生专门为这张桌子服务。

领导者/追随者(Leader/Followers):
在日常生活中,领导者/追随者模式用于管理许多飞机场出租车候车台。在该用例中,出租车扮演“线程”角色,排在第一辆的出租车成为领导者,剩下的出租车成为追随者。同样,到达出租车候车台的乘客构成了必须被多路分解给出租车的事件,一般以先进先出排序。一般来说,如果任何出租车可以为任何顾客服务,该场景就主要相当于非绑定句柄/线程关联。然而,如果仅仅是某些出租车可以为某些乘客服务,该场景就相当于绑定句柄/线程关联。

在 《POSA2》 书中列举的例子都比较复杂,并且书上没有列出完整的代码。但是这两个模式其实都可以在《unix网络编程》一书中找到对应的完整的代码和相关的讨论。

在 半同步/半异步 模式中,需要由模式实现者显示构造一个队列,以便同步层和异步层可以通信。
《unix网络编程》 一书的 “27.12 TCP预先创建线程服务器程序,主线程统一 accept” 的例子中,如果只是从处理 accept 这个事件上看,可以认为这是一个使用了 半同步/半异步 模式的例子。但是从具体的业务处理(即web_child的处理上),仍然可以认为是一个ThreadPerConnection模型,因为在 thread_main 中直接读取请求和发送响应。在这个例子中,就有一个队列:


[b]//这就是一个典型的循环队列的定义,iget 是队列头,iput 是队列尾[/b]
int clifd[MAXNCLI], iget, iput; 

int main( int argc, char * argv[] )
{
  ......
  int listenfd = Tcp_listen( NULL, argv[ 1 ], &addrlen );
  ......

  iget = iput = 0;

  for( int i = 0; i < nthreads; i++ ) {
    pthread_create( &tptr[i].thread_tid, NULL, &thread_main, (void*)i );

  for( ; ; ) {
    connfd = accept( listenfd, cliaddr,, &clilen );
    clifd[ iput ] = connfd;     [b]// 接受到的连接句柄放入队列[/b]
    if( ++iput == MAXNCLI ) iput = 0;  
  }
}

void * thread_main( void * arg )
{
  for( ; ; ) {
    while( iget == iput ) pthread_cond_wait( ...... );
    connfd = clifd[ iget ];     [b]// 从队列中获得连接句柄[/b]
    if( ++iget == MAXNCLI ) iget = 0;
    ......
    web_child( connfd );
    close( connfd );
  }
}




而在 领导者/追随者 模式中,同样是有一个队列的,不过不需要模式实现者显示构造,而是直接使用了操作系统底层的队列。

《unix网络编程》 一书的 “27.11 TCP 预先创建服务器线程,每个线程各自 accept ” 的例子中,就是直接使用了操作系统中关于 accept 的队列。这个例子可以认为是 领导者/追随者 模式的一个例子。

int listenfd;

int main( int argc, char * argv[] )
{
  ......
  listenfd = Tcp_listen( NULL, argv[ 1 ], &addrlen );
  ......
  for( int i = 0; i < nthreads; i++ ){
    pthread_create( &tptr[i].thread_tid, NULL, &thread_main, (void*)i );
  }
  ......
}

void * thread_main( void * arg )
{
  for( ; ; ){
    ......
    [b]// 多个线程同时阻塞在这个 accept 调用上,依靠操作系统的队列[/b]
    connfd = accept( listenfd, cliaddr, &clilen );
    ......
    web_child( connfd );
    close( connfd );
    ......
  }
}


当然,这里提到的操作系统的队列,在 半同步/半异步 模式中虽然没有明显地指出来,但只要是通过操作系统来做 accept ,那么在 半同步/半异步 模式中仍然会隐式地用到。

《POSA2》中,作者的评价:
因为半同步/半异步设计在 web 服务器虚拟内存而不是操作系统内核内排队请求,所以它更具伸缩性。


看了上面的代码之后,明白了为何 ACE 的作者在 《C++网络编程2》 中特意引用了一首诗来“表达我们对 Richard 之持久影响的看法”:

不是在悲哀的冥河之滨,也不是在遥远的
乐土般的平原的清辉中,我们将在死者中间
遇见那些我们一直是其学生的人 ... ...
我们还将相遇,分离,再相遇,
在死者们相遇的地方,在活着的人的唇上


关于不同的客户-服务器编程模型,在《unix网络编程》的 “第27章 客户-服务器程序的其他设计方法”中讨论得很充分,对每种模型的性能也做了很好的分析。
分享到:
评论
1 楼 funing 2012-10-23  
请问下哪儿可以找到POSA上的例子代码呢?

相关推荐

    Half Sync/Half Async Pattern

    ### 半同步/半异步模式 (Half Sync/Half Async Pattern) #### 概述 半同步/半异步(Half Sync/Half Async, HS-HA)架构模式是一种用于复杂并发系统的设计模式,它通过将同步任务与异步任务解耦来优化系统的性能...

    前端开源库-babel-helper-remap-koa2-async-to-generator

    前端开源库-babel-helper-remap-koa2-async-to-generatorbabel-helper-remap-koa2-async-to-generator,将异步函数转换为ES2015生成器(koav2-&gt;koav1)。

    vuex-iframe-sync-iframe /窗口之间的Vuex状态同步。-Vue.js开发

    vuex-iframe-sync英文| 中文iframe /窗口之间的Vuex状态同步您的明星是对我的最大鼓励。 :sparkles:功能:支持ifra vuex-iframe-sync英文| 中文iframe /窗口之间的Vuex状态同步您的明星是对我的最大鼓励。 :sparkles...

    Android代码-android-async-http

    ...Changelog See what is new in ...https://github.com/loopj/android-async-http/blob/1.4.9/CHANGELOG.md Javadoc Latest Javadoc for 1.4.9 release are available here (also included in Maven repository): ...

    android-async-http 源码

    Build Status ...https://github.com/loopj/android-async-http/blob/1.4.9/CHANGELOG.md Javadoc Latest Javadoc for 1.4.9 release are available here (also included in Maven repository): ...

    论文研究-自主虚拟士兵攻击行为研究.pdf

    为了降低线程完成的超时发生率,采用Half-Sync/Half-Async线程池架构建立实时控制系统的线程池,利用最小二乘支持向量回归机(LSSVR)对线程执行时间进行预测估计,再基于估计结果对线程池线程的分配调度优先级别...

    安装python3-aptdaemon所需要的python文件client.py

    安装python3-aptdaemon所需要的python文件,然而,自动生成的可能在新版python中运行,需要替换。位置/usr/lib/python3/dist-packages/aptdaemon/client.py

    前端开源库-sync

    标题“前端开源库-sync”所提及的是一款针对前端开发的开源库,它的主要功能是通过一种称为“节点光纤”(Fibers)的技术,使得原本在JavaScript中的异步函数可以以同步的方式进行调用和执行。这对于前端开发者来说...

    konserve, 带有 core.async的clojuresque key-value/文档存储协议.zip

    konserve, 带有 core.async的clojuresque key-value/文档存储协议 konserve 的... 使用 core.async 语义定义的简单文档存储协议,允许在关联 key-value 存储上使用来自Clojure和ClojureScript的Clojuresque Collectio

    laravel-5-sockets-and-queue-async, Laravel 5 web socket和带有套接字警报回调的队列异步.zip

    laravel-5-sockets-and-queue-async, Laravel 5 web socket和带有套接字警报回调的队列异步 Laravel 5,带有 web sockets和队列异步安装干净的Laravel 5composer create-project laravel/laravel --prefer-dist/path...

    前端开源库-babel-plugin-transform-async-to-promises

    3. **转换过程**:`babel-plugin-transform-async-to-promises`工作原理是,首先识别出`async function`和`await`关键字,然后将它们替换为基于Promise的操作,如`.then()`和`.catch()`。这样,即使目标环境不支持`...

    baserver服务器框架C++ Tcp server

    bas为boost_asio_server(baserver)的简称,是采用Half-Sync/Half-Async模式的服务器框架,使用c++实现,能够大大简化tcp server的开发工作。bas目前实现了以下功能: 1、底层基于boost及asio实现,支持ssl,跨越...

    mongodb-async-driver-2.0.1驱动.zip

    mongodb-async-driver-2.0.1驱动文件 jar MongoDB Async Java Driver Documentation Welcome to the MongoDB Async Java driver documentation hub. Getting Started The Getting Started guide contains ...

    mongodb-async-driver-2.0.1 jar包

    MongoDB是一个流行的开源、分布式数据库系统,以JSON文档为中心,具备高性能、高可用性和可扩展性。MongoDB异步驱动程序(mongodb-async-driver)是为Java开发者设计的一个库,它允许应用程序以非阻塞的方式与...

    hostapd+ssl+libnl.rar

    ./config no-asm shared no-async --prefix=/usr/local/aarch64-linux-gnu-7.4.1/aarch64-linux-gnu --cross-compile-prefix=aarch64-linux-gnu- hostpad 移植 cp defconfig .config vi .config CONFIG_LIBNL32...

    async-http-client-1.9.40.jar

    今天再找一个jar包,可是在网上找的都需要...(async-http-client-1.9.40.jar) maven: &lt;groupId&gt;com.ning&lt;/groupId&gt; &lt;artifactId&gt;async-http-client&lt;/artifactId&gt; &lt;version&gt;1.9.40&lt;/version&gt; &lt;/dependency&gt;

    async-mysql-connector-1.6.jar

    async-mysql-connector-1.6.jar async-mysql-connector-1.6.jar async-mysql-connector-1.6.jar async-mysql-connector-1.6.jar async-mysql-connector-1.6.jar async-mysql-connector-1.6.jar async-mysql-...

    关于禁用weblogic wls-wsat组件的步骤说明

    禁用WLS-WSAT组件的操作分为两大类:非NodeManager模式和NodeManager模式。每种模式下又有两种不同的禁用方法。 ##### 1. 非NodeManager模式 **方法一:在进程启动脚本中添加** - 在WebLogic进程启动脚本中(如:...

    SpringMVC文件上传

    11:01:33,545 DEBUG ThreadPoolAsynchronousRunner:730 - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@5b28c08e -- Running DeadlockDetector[Exiting. No pending tasks.] 11:01:43,558 ...

    前端开源库-babel-plugin-transform-async-to-generator-2

    前端开源库-babel-plugin-transform-async-to-generator-2babel-plugin-transform-async-to-generator-2是babel-plugin-transform-async到generator的一个分支,与此插件保持异步函数的原始参数名略有不同。

Global site tag (gtag.js) - Google Analytics