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

2024-02-12 12:32

本文主要是介绍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 中直接读取请求和发送响应。在这个例子中,就有一个队列:

Java代码   收藏代码
  1. [b]//这就是一个典型的循环队列的定义,iget 是队列头,iput 是队列尾[/b]  
  2. int clifd[MAXNCLI], iget, iput;   
  3.   
  4. int main( int argc, char * argv[] )  
  5. {  
  6.   ......  
  7.   int listenfd = Tcp_listen( NULL, argv[ 1 ], &addrlen );  
  8.   ......  
  9.   
  10.   iget = iput = 0;  
  11.   
  12.   forint i = 0; i < nthreads; i++ ) {  
  13.     pthread_create( &tptr[i].thread_tid, NULL, &thread_main, (void*)i );  
  14.   
  15.   for( ; ; ) {  
  16.     connfd = accept( listenfd, cliaddr,, &clilen );  
  17.     clifd[ iput ] = connfd;     [b]// 接受到的连接句柄放入队列[/b]  
  18.     if( ++iput == MAXNCLI ) iput = 0;    
  19.   }  
  20. }  
  21.   
  22. void * thread_main( void * arg )  
  23. {  
  24.   for( ; ; ) {  
  25.     while( iget == iput ) pthread_cond_wait( ...... );  
  26.     connfd = clifd[ iget ];     [b]// 从队列中获得连接句柄[/b]  
  27.     if( ++iget == MAXNCLI ) iget = 0;  
  28.     ......  
  29.     web_child( connfd );  
  30.     close( connfd );  
  31.   }  
  32. }  



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

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

Java代码   收藏代码
  1. int listenfd;  
  2.   
  3. int main( int argc, char * argv[] )  
  4. {  
  5.   ......  
  6.   listenfd = Tcp_listen( NULL, argv[ 1 ], &addrlen );  
  7.   ......  
  8.   forint i = 0; i < nthreads; i++ ){  
  9.     pthread_create( &tptr[i].thread_tid, NULL, &thread_main, (void*)i );  
  10.   }  
  11.   ......  
  12. }  
  13.   
  14. void * thread_main( void * arg )  
  15. {  
  16.   for( ; ; ){  
  17.     ......  
  18.     [b]// 多个线程同时阻塞在这个 accept 调用上,依靠操作系统的队列[/b]  
  19.     connfd = accept( listenfd, cliaddr, &clilen );  
  20.     ......  
  21.     web_child( connfd );  
  22.     close( connfd );  
  23.     ......  
  24.   }  
  25. }  


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

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


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

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


关于不同的客户-服务器编程模型,在 《unix网络编程》的 “第27章 客户-服务器程序的其他设计方法”中讨论得很充分,对每种模型的性能也做了很好的分析。

这篇关于half-sync/half-async 和 Leader/Followers 模式的主要区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/702597

相关文章

2.1/5.1和7.1声道系统有什么区别? 音频声道的专业知识科普

《2.1/5.1和7.1声道系统有什么区别?音频声道的专业知识科普》当设置环绕声系统时,会遇到2.1、5.1、7.1、7.1.2、9.1等数字,当一遍又一遍地看到它们时,可能想知道它们是什... 想要把智能电视自带的音响升级成专业级的家庭影院系统吗?那么你将面临一个重要的选择——使用 2.1、5.1 还是

Python中@classmethod和@staticmethod的区别

《Python中@classmethod和@staticmethod的区别》本文主要介绍了Python中@classmethod和@staticmethod的区别,文中通过示例代码介绍的非常详细,对大... 目录1.@classmethod2.@staticmethod3.例子1.@classmethod

Golan中 new() 、 make() 和简短声明符的区别和使用

《Golan中new()、make()和简短声明符的区别和使用》Go语言中的new()、make()和简短声明符的区别和使用,new()用于分配内存并返回指针,make()用于初始化切片、映射... 详细介绍golang的new() 、 make() 和简短声明符的区别和使用。文章目录 `new()`

Python中json文件和jsonl文件的区别小结

《Python中json文件和jsonl文件的区别小结》本文主要介绍了JSON和JSONL两种文件格式的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下... 众所周知,jsON 文件是使用php JSON(JavaScripythonpt Object No

结构体和联合体的区别及说明

《结构体和联合体的区别及说明》文章主要介绍了C语言中的结构体和联合体,结构体是一种自定义的复合数据类型,可以包含多个成员,每个成员可以是不同的数据类型,联合体是一种特殊的数据结构,可以在内存中共享同一... 目录结构体和联合体的区别1. 结构体(Struct)2. 联合体(Union)3. 联合体与结构体的

什么是 Ubuntu LTS?Ubuntu LTS和普通版本区别对比

《什么是UbuntuLTS?UbuntuLTS和普通版本区别对比》UbuntuLTS是Ubuntu操作系统的一个特殊版本,旨在提供更长时间的支持和稳定性,与常规的Ubuntu版本相比,LTS版... 如果你正打算安装 Ubuntu 系统,可能会被「LTS 版本」和「普通版本」给搞得一头雾水吧?尤其是对于刚入

python中json.dumps和json.dump区别

《python中json.dumps和json.dump区别》json.dumps将Python对象序列化为JSON字符串,json.dump直接将Python对象序列化写入文件,本文就来介绍一下两个... 目录1、json.dumps和json.dump的区别2、使用 json.dumps() 然后写入文

Python中的异步:async 和 await以及操作中的事件循环、回调和异常

《Python中的异步:async和await以及操作中的事件循环、回调和异常》在现代编程中,异步操作在处理I/O密集型任务时,可以显著提高程序的性能和响应速度,Python提供了asyn... 目录引言什么是异步操作?python 中的异步编程基础async 和 await 关键字asyncio 模块理论

便携式气象仪器的主要特点

TH-BQX9】便携式气象仪器,也称为便携式气象仪或便携式自动气象站,是一款高度集成、低功耗、可快速安装、便于野外监测使用的高精度自动气象观测设备。以下是关于便携式气象仪器的详细介绍:   主要特点   高精度与多功能:便携式气象仪器能够采集多种气象参数,包括但不限于风速、风向、温度、湿度、气压等,部分高级型号还能监测雨量和辐射等。数据采集与存储:配备微电脑气象数据采集仪,具有实时时钟、数据存

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)