把之前发表过的一篇文章贴到自己 blog 中,便于查看。
在
SPServer 中实现了 HSHA 和 LF 两种线程池。
目前的实现还是比较可读的,这两种线程池最主要的处理逻辑各自都被集中到了一个函数中。
先来看看 HSHA 的核心实现代码
http://spserver.googlecode.com/svn/trunk/spserver.cpp
int SP_Server :: start()
{
......
SP_Executor workerExecutor( mMaxThreads, "work" );
SP_Executor actExecutor( 1, "act" );
/* Start the event loop. */
while( 0 == mIsShutdown ) {
event_base_loop( eventArg.getEventBase(), EVLOOP_ONCE );
for( ; NULL != eventArg.getInputResultQueue()->top(); ) {
SP_Task * task = (SP_Task*)eventArg.getInputResultQueue()->pop();
workerExecutor.execute( task );
}
for( ; NULL != eventArg.getOutputResultQueue()->top(); ) {
SP_Message * msg = (SP_Message*)eventArg.getOutputResultQueue()->pop();
......
actExecutor.execute( outputCompleted, arg );
}
}
......
}
一些细节都被去掉了。从这段代码可以看到,HSHA 的处理流程是:
1.运行 start 函数的线程称为 event_loop 线程,负责 recv/send 。
所有的 recv/send 都在 event_base_loop 这个函数调用上完成的。
这个层就是属于异步层。
2. event_base_loop 在 recv 的时候,会调用 MsgDecoder.decode 函数,
如果 decode 返回 OK ,说明完整地读入数据了,那么就把对应的数据放入
eventArg.mInputResultQueue 里面。
在 send 的时候,如果把一个 Message 完整地发送了,
那么就把这个 Message 放入 eventArg.mOutputResultQueue。
这两个就是队列,队列里面保存的数据一般称为完成事件。
3.workerExecutor 和 actExecutor 就是同步层。
由于完成事件的处理可能会涉及很复杂的处理,可能会使用到数据库或者其他,
因此不能直接使用 event_loop 线程,而是使用线程池。
这个就是同步层。
再来看 LF 的核心代码
http://spserver.googlecode.com/svn/trunk/splfserver.cpp
int SP_LFServer :: run()
{
......
mThreadPool = new SP_ThreadPool( mMaxThreads );
for( int i = 0; i < mMaxThreads; i++ ) {
mThreadPool->dispatch( lfHandler, this );
}
......
}
void SP_LFServer :: lfHandler( void * arg )
{
SP_LFServer * server = (SP_LFServer*)arg;
for( ; 0 == server->mIsShutdown; ) {
/* follower begin */
server->handleOneEvent();
}
}
void SP_LFServer :: handleOneEvent()
{
SP_Task * task = NULL;
SP_Message * msg = NULL;
/* follower wait */
pthread_mutex_lock( &mMutex );
/* follower end */
/* leader begin */
for( ; 0 == mIsShutdown && NULL == task && NULL == msg; ) {
if( mEventArg->getInputResultQueue()->getLength() > 0 ) {
task = (SP_Task*)mEventArg->getInputResultQueue()->pop();
} else if( mEventArg->getOutputResultQueue()->getLength() > 0 ) {
msg = (SP_Message*)mEventArg->getOutputResultQueue()->pop();
}
if( NULL == task && NULL == msg ) {
event_base_loop( mEventArg->getEventBase(), EVLOOP_ONCE );
}
}
/* leader end */
pthread_mutex_unlock( &mMutex );
/* worker begin */
if( NULL != task ) task->run();
if( NULL != msg ) mCompletionHandler->completionMessage( msg );
/* worker end */
}
在 run 函数中,启动线程池中的多个线程运行 lfHandler ,
由 lfHandler 不断地运行 handleOneEvent 。
线程的角色转变在上面的注释中可以很清楚地看到。
由于这里的实现比较简单,LF 线程池的线程都是预先创建的,
并且没有实现线程池之外的线程可以加入的功能,
所以在 leader 切换为 worker,并且提升一个 follower 为 leader 的时候,
只需要用一个 mutex 就可以解决了。
分享到:
相关推荐
### 半同步/半异步模式 (Half Sync/Half Async Pattern) #### 概述 半同步/半异步(Half Sync/Half Async, HS-HA)架构模式是一种用于复杂并发系统的设计模式,它通过将同步任务与异步任务解耦来优化系统的性能...
...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): ...
前端开源库-babel-helper-remap-koa2-async-to-generatorbabel-helper-remap-koa2-async-to-generator,将异步函数转换为ES2015生成器(koav2->koav1)。
vuex-iframe-sync英文| 中文iframe /窗口之间的Vuex状态同步您的明星是对我的最大鼓励。 :sparkles:功能:支持ifra vuex-iframe-sync英文| 中文iframe /窗口之间的Vuex状态同步您的明星是对我的最大鼓励。 :sparkles...
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): ...
然而,这种模式会导致代码难以理解和调试,也就是我们常说的“回调地狱”。为了解决这个问题,出现了Promise、async/await等解决方案,而“前端开源库-sync”则是另辟蹊径,采用了Fibers技术。 Fibers是Node.js的一...
为了降低线程完成的超时发生率,采用Half-Sync/Half-Async线程池架构建立实时控制系统的线程池,利用最小二乘支持向量回归机(LSSVR)对线程执行时间进行预测估计,再基于估计结果对线程池线程的分配调度优先级别...
安装python3-aptdaemon所需要的python文件,然而,自动生成的可能在新版python中运行,需要替换。位置/usr/lib/python3/dist-packages/aptdaemon/client.py
bas为boost_asio_server(baserver)的简称,是采用Half-Sync/Half-Async模式的服务器框架,使用c++实现,能够大大简化tcp server的开发工作。bas目前实现了以下功能: 1、底层基于boost及asio实现,支持ssl,跨越...
js代码-async/await函数实现
3. **转换过程**:`babel-plugin-transform-async-to-promises`工作原理是,首先识别出`async function`和`await`关键字,然后将它们替换为基于Promise的操作,如`.then()`和`.catch()`。这样,即使目标环境不支持`...
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和带有套接字警报回调的队列异步 Laravel 5,带有 web sockets和队列异步安装干净的Laravel 5composer create-project laravel/laravel --prefer-dist/path...
总的来说,"mongodb-async-driver-2.0.1.jar"这个包是Java开发者与MongoDB数据库交互的强大工具,它通过异步I/O和事件驱动的编程模型,提高了应用的并发能力和响应速度。通过这个驱动,开发者可以充分利用MongoDB的...
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 ...
商业编程-源码-数据库技术源代码 async_demo.zip
【标题】"商业编程-源码-数据库技术源代码 async_exe.zip" 提供的是与数据库技术相关的源代码,其中可能包含用于处理商业环境中的数据存储、检索和管理的程序。async_exe表明这部分源代码可能涉及异步执行机制,这...
js代码-async/await的调用
今天再找一个jar包,可是在网上找的都需要...(async-http-client-1.9.40.jar) maven: <groupId>com.ning</groupId> <artifactId>async-http-client</artifactId> <version>1.9.40</version> </dependency>
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-...