我有一个客户端 - 服务器架构,其中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
的速度?
我没有发布代码,因为很难从项目中提取代码,但如果你不理解我的描述,我可以写一个例子。
谢谢。
答案 0 :(得分:1)
1)当调用async.read完成处理程序时,并不意味着某些数据可用,这意味着当时可用的所有数据已经被读取(除非您指定了)限制完成条件)。因此,后续的sync.read可能会等到更多数据到达。
2)阻止完成处理程序是一个坏主意,因为你实际上阻止了所有其他完成处理程序和发布到io_service
的其他函子。考虑改变你的设计。
答案 1 :(得分:1)
如果您要进行异步设计,请不要混合使用某些同步部件。用异步替换所有同步读写。读取和写入都会阻塞您的线程,而异步变量则不会。
此外,如果您在读取标头后确切知道了预期字节数,则应该准确请求该字节数。
如果你不知道,你可以选择一个async_read_some
,其大小与你期望的最大消息一样。 async_read_some
将通知您实际读取了多少字节。