对于带有单个接受器的线程 boost::asio 服务器,我们是不是需要每个线程多个 io_service

Posted

技术标签:

【中文标题】对于带有单个接受器的线程 boost::asio 服务器,我们是不是需要每个线程多个 io_service【英文标题】:Do we need multiple io_service per thread for threaded boost::asio server with a single acceptor对于带有单个接受器的线程 boost::asio 服务器,我们是否需要每个线程多个 io_service 【发布时间】:2012-06-16 03:41:51 【问题描述】:

我对@9​​87654322@ 没有多少经验。我有一些非常基本的问题。

我是否需要在不同的thread 下拥有不同的io_service 和不同的socket,但需要一个acceptor,才能在线程服务器中处理客户端?

我相信我必须为新客户使用不同的套接字。但是如果所有线程都使用相同的io_service 会是并行的吗?

我在 asio 部分浏览 http://en.highscore.de/cpp/boost/index.html 这表示我需要在不同的线程中有不同的 io_services 才能实现并行化。

如果我打算创建一个 Server 类,每次在 acceptor.async_accept 中出现新客户端时创建一个 new TCPsessionTCPSession ctor 创建一个io_service 和一个thread 并在它自己的线程中运行io_service.run() 这会是一个好的设计吗?

但是,在这个设计中,我将在哪里加入所有这些线程?我是否需要另一个io_service 用于main,这样它甚至在获得新客户之前也不会终止?

【问题讨论】:

【参考方案1】:

在单个线程中运行的单个io_service 可以为您项目中的所有 asio 对象提供服务。在这样的设计中,I/O 仍然是“并行的”,因为它是非阻塞的、异步的;但是由于io_service::run() 是在一个线程中运行的,所有的完成处理程序都将被一个接一个地串行调用。

要在多个 CPU 上扩展您的网络模块,您可以使用以下两种方法之一:thread-per-core、io_service-per-core - 请参阅 HTTPServer2 and HTTPServer3 examples。

在任何情况下,在我看来,为 TCPSession 创建一个线程或 io_service 似乎是不必要的开销 - 想想你有数千个 TCPSessions 的情况......

【讨论】:

那么每个会话线程会做什么?例如我不应该在一个线程中有一个会话吗?使每个会话并行?但是我应该一次有 不,你不需要那个。请阅读以下内容:boost.org/doc/libs/1_47_0/doc/html/boost_asio/overview/core/…。您可能需要额外线程的唯一情况是 TCPSession 完成处理程序太重(例如,执行耗时的 DB 操作等)。但是无论如何,您的应用程序将无法扩展,因此您必须更改设计以将一些工作拆分或移出完成处理程序。 所以如果我每个会话只有一个不同的套接字会好吗?我可以先在单线程中开发整个东西吗?然后切换到多线程? 当然,TCPSession 会封装它自己的 tcp::socket,但是所有这些套接字都可以由同一个 io_service 提供服务(即你可以用同一个 io_service 创建它们)。如果您使用 io_sevice-per-cpu 模型,那么您可以开发 TCPSessions 而无需考虑最终将拥有多少个 io_service。只需创建 io-service 池(每个 io_service 将在自己的线程中),每次创建 TCPSession 时,从池中获取一个 io_service。最初您可以将池大小设置为 1,然后将其增加到 boost::thread::hardware_concurrency() 。

以上是关于对于带有单个接受器的线程 boost::asio 服务器,我们是不是需要每个线程多个 io_service的主要内容,如果未能解决你的问题,请参考以下文章

Boost.Asio、tcp::iostream 和多线程

将 Boost.Log 与 Boost.Asio 服务一起使用

将 std::bind 应用于带有参数 <boost::asio::ip::tcp::socket> 的函数时出错?

boost::asio io_service 停止特定线程

boost::asio async_accept 杀死 ioservice

使用 boost 创建线程池