【问题标题】:BOOST ASIO multi-io_service RPC framework design RFCBOOST ASIO multi-io_service RPC 框架设计 RFC
【发布时间】:2011-10-10 05:53:01
【问题描述】:

我正在研究 RPC 框架,我想使用多 io_service 设计将执行 IO(前端)的io_objects 与执行 RPC 工作的线程(后端)分离。

前端应该是单线程的,后端应该有一个线程池。我正在考虑使用条件变量使前端和后端同步的设计。但是,boost::threadboost::asio 似乎没有混合——即,似乎条件变量 async_wait 支持不可用。我有一个关于这个问题的问题here

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

【问题讨论】:

    标签: c++ boost-asio rpc system-design


    【解决方案1】:

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

    另外我假设你的前端是单线程的,只是为了避免从多个线程写入同一个套接字的竞争条件。

    使用io_service::strandtutorial)也可以达到同样的目的。你的前端可以通过io_service::strand进行MT同步。从后端到前端的所有posts(以及从前端到前端的处理程序,如handle_connect 等)都应该由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包裹。

    【讨论】:

    • 不,我已经阅读了大多数示例的源代码:DI 表示用于执行网络 IO 的单线程 IO 服务,以及具有执行 RPC 的多个线程的 IO 服务:D
    • 为什么选择这个设计?有什么好处吗?
    • 一个线程可以轻松复用数千个连接的客户端,只要不涉及非确定性复杂度的操作(如硬盘IO)。由于所讨论的应用程序是一个复杂的事件处理引擎,因此 RPC 调用通常会写入磁盘。这是第一个原因,其次我想对 RPC 服务进行单元测试,移除异步/基于套接字的 IO 大大简化了这一点。
    • 两个io_servicess 怎么样?第一个(前端)在单线程中运行,第二个(后端)由多个线程运行。通过调用io_service::post()进行前端和后端交换任务,不需要condition_variable或任何其他显式同步
    【解决方案2】:

    如果您的后端是调用任何io_service::run(), io_service::run_one(), io_service::poll(), io_service::poll_one() 函数的线程池,并且您的处理程序需要访问共享资源,那么您仍然必须注意以某种方式将这些共享资源锁定在处理程序本身中。

    鉴于问题中发布的信息数量有限,鉴于上述警告,我认为这将正常工作。

    但是,在发布时,设置必要的完成端口和等待会产生一些可衡量的开销——开销可以避免使用后端“队列”的不同实现。

    在不知道您需要完成的具体细节的情况下,我建议您查看pipelines 或更简单的concurrent queue 的线程构建块。

    【讨论】:

      猜你喜欢
      • 2011-06-16
      • 2017-09-17
      • 2012-11-26
      • 2011-12-18
      • 2015-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多