代码之家  ›  专栏  ›  技术社区  ›  Hassan Syed

boost::asio:线程本地异步事件

  •  4
  • Hassan Syed  · 技术社区  · 15 年前

    我将在我的服务器应用程序中创建x个线程。x是机器上的核心数量,这些线程将被(非超线程)核心绑定。当然,使用这个方案,我希望在线程之间分布传入的连接,以确保一旦将连接分配给线程,它将只在该特定线程之外提供。这是如何在Boost::ASIO中实现的?

    我在想:单人间 socket 绑定到多个共享的地址 io_service 每个线程都有自己的线程 信息服务 . 这一推理是正确的吗?

    编辑: 看来我得自己回答这个问题了。

    3 回复  |  直到 15 年前
        1
  •  5
  •   janm    15 年前

    是的,你的推理基本上是正确的。您将为每个核心创建一个线程,为每个线程创建一个IO服务实例,并在每个线程中调用IO服务.run()。

    然而,问题是你是否真的会那样做。我看到的问题是:

    • 您可以最终得到非常繁忙的内核和空闲的内核,这取决于您的连接中工作是如何平衡的。对核心缓存命中的微观优化可能意味着当“最佳”核心尚未准备好时,最终会失去让空闲核心工作的能力。

    • 在套接字速度(即:慢)下,您将从CPU缓存命中中获得多少胜利?如果一个连接需要足够的CPU来保持一个核心繁忙,而您只需要和核心一样多的连接,那就太好了。否则,无法移动工作来处理工作负载的变化可能会破坏从缓存命中中获得的任何胜利。如果你在每个线程中做了很多不同的工作,那么缓存就不会变得那么热。

    • 如果你只是在做I/O,那么不管怎样,缓存的胜利可能不会那么大。取决于你的实际工作量。

    我的建议是拥有一个IO服务实例,并在每个核心的线程中调用IO服务.run()。如果您的性能不足,或者每个连接有大量CPU的连接类,并且您可以获得缓存胜利,那么将这些连接转移到特定的IO服务实例。

    在这种情况下,您应该进行分析,看看有多少缓存未命中会让您付出代价,以及在哪里。

        2
  •  2
  •   Olliwaa    15 年前

    如果您的服务器应用程序应该在Windows计算机上运行,那么您应该考虑使用IO完成端口。

    它能够将活动线程的数量限制为核心的数量。它将IO事件从理论上无限数量的套接字分布到活动线程。调度由操作系统完成。 Here 是一个很好的例子。

        3
  •  0
  •   cairol    15 年前

    你可以用单人间 io_service 它由多个线程和 strand 以确保连接始终由同一线程处理。看一看 HTTP server 3 example .