基本上,我想要实现的是实现一个通用的多线程TCP服务器,它可以处理2个不同服务器使用的任意请求,需求略有不同 .
我的要求是:
-
在收到整个初始请求之前,无法开始处理请求 . (基本上,我有一个固定大小的请求标头,其中包括整个请求的大小) .
-
处理请求可能会导致向请求客户端发送多条响应消息 . IE,通常情况下,请求可以在一个响应中处理,但有时,为了响应长时间运行的数据库事务,我需要ping回客户端,让他们知道我还在工作并且没有超时连接 .
为了实现这一点,我一直密切关注来自boost v1.44的HTTP服务器示例#2 . 一般来说,这个例子适用于简单的案例 . 我注意到的是,当我扩展到同时处理多个请求时,我所做的更改以某种方式导致所有请求被单个线程串行处理 . 显然,我做错了什么 .
由于雇主的限制,我无法发布我正在使用的全部实际代码,但足以说明,我保持异步调用以接受新连接,但已经用同步调用替换了异步读/写 . 如果您认为需要查看特定部分,我可以看到我能做些什么 .
本质上,我正在寻找的是如何将boost :: asio用于多线程TCP服务器的指针,其中单个连接由具有同步I / O的单个线程处理 . 再次,请记住,我的抽象是基于http服务器示例#2(每个CPU一个io_service),但我可以灵活交替
3 回答
一些诊断:您可以在以下代码中使用之前打印
io_service_pool_.get_io_service()
的值吗?在将其传递给
new_connection_.reset()
之前,您需要将其存储在临时中;也就是说,不要为此测试调用两次get_io_service()
.我们首先要确保你得到一个新的
io_service
.如果您正在进行大量的同步I / O,则并发性仅限于您拥有的线程数 . 我建议为你所有的异步I / O(即:所有的通信,定时器)提供一个io_service,然后决定如何处理同步I / O.
对于同步I / O,您需要确定峰值并发性 . 因为它是同步的并且它是I / O,所以你需要更多的CPU线程,并且决定将基于你想要多少I / O并发 . 使用单独的io_service,然后使用io_service :: dispatch()将工作分配到执行同步工作负载的线程中 .
这样做可以避免阻塞I / O调用停止处理其他异步事件的问题 .
Boost.Asio documentation建议每个应用程序使用一个
io_service
,并从线程池中调用io_service::run
.对我来说,为什么你不能使用异步
read
和write
与deadline_timer
对象一起定期ping客户端也不明显 . 这种设计几乎肯定会比使用同步reads
和writes
的每个连接线程更好地扩展 .