根据以下帖子,只有当前正在执行的插槽完成后才会提供发出的信号 Wait for a SLOT to finish the execution with Qt
我有一个基于ssl socket的客户端 - 服务器通信应用程序,它是单线程的。
connect(socket, &QSslSocket::readyRead, [&]() { myObject.Read(); });
客户&服务器互相发送一些自定义消息。无论何时发送或接收消息,它们都会发送ACK
个字节(00)
大多数时候,我注意到当Read()
处于执行之间时,下一个readyRead()
就会被提供!我把调试语句放在开头和开头。结束myObject->Read()
。他们确认,再次调用开始调试&再次。断点也是如此。
当接收到太多数据时,会创建一个递归堆栈帧太多Read()
s。它要么减慢app GUI的速度,要么崩溃
通常,当客户端尝试作为myObject->Read()
的一部分发送ACK时,会发生此递归。在此期间readyRead()
偶然发出信号&也得到了服务。然而,之前信号的位置仍在处理中。
问题:
注意:
- 默认情况下,单个线程的Qt::ConnectionType
为DirectConnection
。我也试过QueuedConnection
,但结果是一样的
- myObject.Read()
非常复杂,还有许多其他函数调用。如果这导致问题,那么让我知道我应该寻找什么。编写实际代码是不切实际的。
答案 0 :(得分:2)
readyRead()
的递归调用正在发生,因为事件循环在两者之间被释放。以下函数导致事件循环被释放:
QCoreApplication::processEvents()
SslSocket::flush()
第一个是可以理解的,因为它的意思是。但第二个flush()
令人惊讶。它的documentation没有说明。至少在我的调试中,它表明,每当调用flush()
时,都会调用后续的readyRead()
并进行照顾。在Qn中也可以看到。
processEvent()
旨在使GUI在高负载数据期间更具响应性。但似乎我们需要为此做出另一种选择。