2011-07-21 84 views
1

我正在使用RPC框架,我想使用多io_service设计来解耦执行IO(前端)执行RPC工作的线程的io_objects (后端)。BOOST ASIO multi-io_service RPC框架设计RFC

前端应该是单线程的,而后端应该有一个线程池。我正在考虑一个设计,使前端和后端使用条件变量进行同步。但是,似乎boost::threadboost::asio不会混淆--i.e。,似乎条件变量async_wait支持不可用。我有一个关于这个问题的问题here

我发现io_service::post()可能用于同步两个io_service对象。我在下面附上了一张图,我只是想知道我是否正确理解了post机制,并认为这是一个明智的实现。

rpc system implementation

回答

1

如果后端是一个线程池调用任何io_service::run(), io_service::run_one(), io_service::poll(), io_service::poll_one()功能和处理程序(一个或多个)需要访问共享资源,那么你还是要照顾到锁定这些共享资源以某种方式在处理程序本身。

鉴于问题中张贴的信息量有限,我会假设这会在上面的警告中正常工作。

但是,发布时有一些可测量的开销,用于设置必要的完成端口和等待 - 开销,您可以避免使用不同的后端“队列”实现。

如果不知道您需要完成的具体细节,我建议您查看pipelines的线程构建块,或者更简单地查看concurrent queue

2

我假设你用“a single io_service and a thread pool calling io_service::run()

此外,我认为你的头端是单线程的,只是为了避免从多个线程的竞争条件写入同一插座。

使用io_service::strandtutorial)可以实现相同的目标。您的前端可以通过io_service::strand进行MT同步。从后端至前端(并从前端处理程序来像handle_connect等前端)所有posts应由strand缠绕,这样的事:

后端 - >前端:

io_service.post(front_end.strand.wrap(
    boost::bind(&Front_end::send_response, front_end_ptr))); 

或前端 - >前端:

socket.async_connect(endpoint, strand.wrap(
    boost::bind(&Front_end::handle_connect, shared_from_this(), 
    boost::asio::placeholders::error))); 

而从前端的所有帖子到后端不应该由strand包裹。

+0

不,我已阅读了大部分示例的源代码:D我的意思是单线程IO服务用于执行联网IO,以及具有多线程执行RPC的IO服务:D –

+1

为什么选择此设计?有什么好处? –

+0

只要不涉及具有非确定性复杂性的操作(如硬盘IO),单个线程就可以轻松地复用数千个连接的客户端。由于有问题的应用程序是一个复杂的事件处理引擎,RPC调用通常会写入磁盘。这是第一个原因,其次我想单元测试RPC服务,并且删除基于异步/基于套接字的IO可以大大简化这一点。 –