为什么执行 socket::readyRead() 的新信号,即使其较早的插槽仍在处理中?

Why a new signal for socket::readyRead() is executed, even when its earlier slot is still processing?

根据以下内容post,仅当当前正在执行的插槽完成后,才会提供发出的信号。

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

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

客户端和服务器互相发送一些自定义消息。每当发送或接收消息时,它们都会发送 ACK 字节 (00)。
大多数时候,我注意到当 Read() 在执行之间时,会提供下一个 readyRead() !我将调试语句放在 myObject->Read() 的开头和结尾。他们确认,开始调试被一次又一次地调用。同样观察到断点。

当接收到太多数据时,会创建一个包含太多 Read() 的递归堆栈帧。它要么会降低应用程序 GUI 的速度,要么会崩溃。
通常,当客户端尝试发送 ACK 作为 myObject->Read() 的一部分时,就会发生这种递归。在此期间,readyRead() 被偶然发出信号并得到服务。但是之前信号的slot还在处理中

问题

:
- 默认情况下,对于单线程,Qt::ConnectionTypeDirectConnection。我也试过 QueuedConnection,但结果是一样的。
- myObject.Read() 非常复杂并且有许多其他函数调用。如果这是导致问题的原因,请告诉我应该寻找什么。编写它的实际代码是不切实际的。

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

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

第一个是可以理解的,因为它就是为此而生的。但是第二个 flush() 完全出人意料。它的 documentation 没有这样说明。至少在我的调试中它表明,每当调用 flush() 时,都会调用并满足后续的 readyRead() 。也可以在 Qn 中查看。

processEvent() 旨在使 GUI 在高数据加载期间响应更快。但看来,同样的事情,我们需要另作选择。