• Boost.ASIO简要分析-5 多io_service


    5. 多io_service

    前面那篇讲到了多线程的用法。这篇讲一下多io_service的用法,大家可参考下官方提供的HTTP Server 2(an io_service-per-CPU)这个例子。

    官方提供的例子中,使用方法很简单,建立一个io_service_pool,然后对每一个io_service开一个线程去让它跑起来(毕竟,io_service::run这个函数在有任务的时候会一直工作的,只有开多个线程才做到不影响别的io_service)。当然,我们也可以为每个io_service开多个线程,这样才不会存在上一篇中说到的多线程问题。

    下面以Windows平台讨论io_service,看下io_service的构造过程在Windows下的实现

    win_iocp_io_service::win_iocp_io_service(
    
    boost::asio::io_service& io_service, size_t concurrency_hint)
    
      : boost::asio::detail::service_base<win_iocp_io_service>(io_service),
    
    iocp_(),
    
    outstanding_work_(0),
    
    stopped_(0),
    
    stop_event_posted_(0),
    
    shutdown_(0),
    
    gqcs_timeout_(get_gqcs_timeout()),
    
    dispatch_required_(0)
    
    {
    
    BOOST_ASIO_HANDLER_TRACKING_INIT;
    
    iocp_.handle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0,
    
    static_cast<DWORD>(concurrency_hint < DWORD(~0)
    
            ? concurrency_hint : DWORD(~0)));
    
    if (!iocp_.handle)
    
      {
    
    DWORD last_error = ::GetLastError();
    
    boost::system::error_code ec(last_error,
    
    boost::asio::error::get_system_category());
    
    boost::asio::detail::throw_error(ec, "iocp");
    
      }
    
    }

    通过源码,我们可以发现每个io_service在构造的过程中,会创建一个IOCP。

    创建好之后,我们就可以使用这个IOCP了,

    boost::system::error_code win_iocp_io_service::register_handle(
    
    HANDLE handle, boost::system::error_code& ec)
    
    {
    
    if (::CreateIoCompletionPort(handle, iocp_.handle, 0, 0) == 0)
    
      {
    
    DWORD last_error = ::GetLastError();
    
    ec = boost::system::error_code(last_error,
    
    boost::asio::error::get_system_category());
    
      }
    
    else
    
      {
    
    ec = boost::system::error_code();
    
      }
    
    return ec;
    
    }

    哦,看着就这么简单。

    在io_service类代码中发现add_service这么个函数

    /// Add a service object to the io_service.
    
    /**
    
       * This function is used to add a service to the io_service.
    
       *
    
       * @param ios The io_service object that owns the service.
    
       *
    
       * @param svc The service object. On success, ownership of the service object
    
       * is transferred to the io_service. When the io_service object is destroyed,
    
       * it will destroy the service object by performing:
    
       * @code delete static_cast<io_service::service*>(svc) @endcode
    
       *
    
       * @throws boost::asio::service_already_exists Thrown if a service of the
    
       * given type is already present in the io_service.
    
       *
    
       * @throws boost::asio::invalid_service_owner Thrown if the service's owning
    
       * io_service is not the io_service object specified by the ios parameter.
    
       */
    
    template <typename Service>
    
    friend void add_service(io_service& ios, Service* svc);

    从注释可以看到,io_service之间可以相互转移service对象。单io_service应该不会用到这个函数吧。

  • 相关阅读:
    加法图灵机
    Experiment 1
    进制转换
    快速排序
    辗转相除、线段交点、多角形面积公式
    JS如何优雅监听容器高度变化
    解决react和其他框架之间的交互问题
    MacBook Pro触控板手势
    代理 请求登录失效(显示未登录)问题
    Web端 长按事件
  • 原文地址:https://www.cnblogs.com/SudoSky/p/4524590.html
Copyright © 2020-2023  润新知