带有asio的多插槽架构

时间:2012-12-07 16:32:39

标签: c++ performance sockets client-server boost-asio

我有一个客户端 - 服务器架构,其中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的速度?

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

谢谢。

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

如果您要进行异步设计,请不要混合使用某些同步部件。用异步替换所有同步读写。读取和写入都会阻塞您的线程,而异步变量则不会。

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

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