2

我有一个用 C++ 编写的应用程序,它使用 boost::asio。它侦听套接字上的请求,并为每个请求执行一些 CPU 绑定的工作(例如,没有磁盘或网络 I/O),然后以响应响应。

该应用程序将在多核系统上运行,因此我计划每个内核(至少)1 个线程来并行处理请求。

这里最好的方法是什么?需要考虑的事情:

  • 我需要一个固定大小的线程池(例如每个 CPU 1 个线程)
  • 如果到达的请求比我拥有的线程多,那么它们需要排队(可能在 o/s 套接字层?)

目前服务器是单线程的:

  • 它等待客户端请求
  • 一旦收到请求,它就会执行工作,并将响应写回,然后开始等待下一个请求

更新:

更具体地说:我应该使用什么机制来确保如果服务器很忙,传入的请求会排队?我应该使用什么机制在 N 个线程(每个核心 1 个)之间分配传入请求?

4

3 回答 3

2

我不认为有太多需要考虑的内容是您尚未涵盖的。

如果它确实受 CPU 限制,那么添加超出内核数量的线程对您没有多大帮助,除非您将有很多请求。在这种情况下,监听队列可能会或可能不会满足您的需求,最好让一些线程接受连接并自己排队。检查系统的侦听积压值并尝试使用线程数。

更新:

listen() 有第二个参数,即您请求的 OS/TCP 队列深度。您可以将其设置为操作系统限制。除此之外,您还需要使用系统旋钮。在我当前的系统上,它是 128,所以它不是很大,但也不是微不足道的。检查您的系统并考虑您是否真的需要比默认值更大的东西。

除此之外,您还可以走几个方向。考虑 KISS - 在实际需要之前没有复杂性。从简单的事情开始,比如有一个线程来接受连接(达到一定限制)并将它们放入队列中。工作线程拾取它们、处理、写入结果并关闭套接字。

以我发行版 Boost 更新的当前速度(以及我缺乏自己编译它的意愿),在我使用 ASIO 之前将是 2012 年 - 所以我无能为力。

于 2009-07-22T20:33:45.367 回答
1

王牌 http://www.cs.wustl.edu/~schmidt/ACE/book1/

它有你需要的一切。线程管理和队列以及一个额外的好处是编写 Socket 服务器的可移植方式。

于 2009-07-22T20:33:20.657 回答
1

如果您使用 basic_socket_acceptor 的重载构造函数来绑定和侦听给定的端点,它使用 SOMAXCONN 作为调用 listen() 中的待处理连接的积压。我认为(不太确定)这在 Windows 中映射到 250。因此,网络服务提供商将(默默地)接受客户端连接达到此限制并将它们排队供您的应用程序处理。您的下一个接受呼叫将从该队列中弹出一个连接。

于 2009-07-23T13:09:57.443 回答