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

时间:2017-10-05 01:49:43

标签: c++ qt sockets qt-signals qt-slot

根据以下帖子,只有当前正在执行的插槽完成后才会提供发出的信号 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框架是否可以在两者之间提供信号?
  • 如何解决此特定于套接字的方案?

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

1 个答案:

答案 0 :(得分:2)

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

  1. QCoreApplication::processEvents()
  2. SslSocket::flush()
  3. 第一个是可以理解的,因为它的意思是。但第二个flush()令人惊讶。它的documentation没有说明。至少在我的调试中,它表明,每当调用flush()时,都会调用后续的readyRead()并进行照顾。在Qn中也可以看到。

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