1

我有一个客户端 - 服务器架构,有 10 个服务器,与一个客户端永久连接,该软件是用 C++ 编写的,并使用 boost asio 库。所有连接都是在初始化阶段创建的,并且在执行过程中始终处于打开状态。当客户端需要一些信息时,向所有服务器发送请求。每个服务器都会找到所需的信息并回答客户端。

在客户端中,有一个线程负责接收来自所有套接字的消息,特别是,我只使用一个io_services,每个套接字都有一个 async_read。

当消息到达其中一个套接字时,async_read读取作为消息头的前 N ​​位,然后调用使用read(同步)读取消息其余部分的函数。对于服务器端,标头和消息的其余部分通过单个write(同步)发送。

然后,架构可以正常工作,但我注意到有时同步read需要比平时更多的时间(~0.24 秒)。理论上,数据已经准备好被读取,因为当已经读取了标头read时调用了同步。async_read我还看到,如果我只使用一台服务器而不是 10 台,则不会出现此问题。此外,我注意到这个问题不是因为消息的维度引起的。

是否有可能因为io_service无法处理所有 10 而出现问题async_read?特别是,如果所有套接字同时收到一条消息,是否会io_service失去一些时间来管理队列并减慢我的同步速度read

我没有发布代码,因为很难从项目中提取出来,但如果你不理解我的描述,我可以写一个例子。

谢谢你。

4

2 回答 2

1

如果您选择异步设计,请不要混入一些同步部分。用异步读取和写入替换所有同步读取和写入。读取和写入都会阻塞您的线程,而异步变体不会。

此外,如果您在读取标头后准确地知道预期的字节数,您应该准确地请求该字节数。

如果您不知道,您可以选择async_read_some具有您期望的最大消息大小的单个。async_read_some将通知您实际读取了多少字节。

于 2012-12-08T19:17:24.343 回答
1

1)当 async.read 完成处理程序被调用时,这并不意味着某些数据可用,这意味着该时刻所有可用的数据都已被读取(除非您指定了限制完成条件)。因此后续的 sync.read 可能会等到更多数据到达。

2) 阻止完成处理程序是一个坏主意,因为您实际上阻止了所有其他完成处理程序和其他发布到该处理程序的函子io_service。考虑改变你的设计。

于 2012-12-07T18:17:26.067 回答