6

根据以下帖子,仅在当前执行的插槽完成后才提供发出的信号。
等待 SLOT 用 Qt 完成执行

我有一个基于 ssl 套接字的客户端-服务器通信应用程序,它是单线程的。

connect(socket, &QSslSocket::readyRead, [&]() { myObject.Read(); });

客户端和服务器相互发送一些自定义消息。无论何时发送或接收消息,它们都会发送ACK字节(00)。
大多数时候,我注意到Read()在执行之间时,下一个readyRead()是执行的!我将调试语句放在myObject->Read(). 他们确认,开始调试被一次又一次地调用。断点也是如此。

当接收到太多数据时,会创建一个包含太多Read()s 的递归堆栈帧。它要么减慢应用程序 GUI 的速度,要么崩溃。
通常,当客户端尝试将 ACK 作为myObject->Read(). 在此期间,readyRead()偶然发出信号并得到服务。然而,前一个信号的时隙仍在处理中。

问题

  • 当插槽仍在中间(单线程)时,Qt 框架是否可以在两者之间提供信号?
  • 如何修复此套接字特定场景?

注意
- 默认情况下,单线程Qt::ConnectionTypeDirectConnection. 我也试过了QueuedConnection,但结果是一样的。
-myObject.Read()相当复杂并且有许多其他的函数调用。如果这引起了问题,那么让我知道我应该寻找什么。编写它的实际代码是不切实际的。

4

1 回答 1

2

readyRead()由于事件循环在两者之间被释放,因此发生了递归调用。以下函数导致事件循环被释放:

  1. QCoreApplication::processEvents()
  2. SslSocket::flush()

第一个是可以理解的,因为它是为此而生的。但第二次flush()完全出乎意料。它的文档没有这样说明。至少在我的调试中,它表明,无论何时调用,都会调用和满足flush()后续的。readyRead()在 Qn 中也可以看到。

processEvent()旨在使 GUI 在数据的高负载期间更具响应性。但似乎,我们需要为此做出另一个选择。

于 2017-10-05T10:29:45.430 回答