【发布时间】:2017-10-05 01:49:43
【问题描述】:
根据以下帖子,仅在当前执行的插槽完成后才会提供发出的信号。
Wait for a SLOT to finish the execution with Qt
我有一个基于 ssl 套接字的客户端-服务器通信应用程序,它是单线程的。
connect(socket, &QSslSocket::readyRead, [&]() { myObject.Read(); });
客户端和服务器互相发送一些自定义消息。无论何时发送或接收消息,它们都会发送 ACK 字节 (00)。
大多数时候,我注意到当Read() 在执行之间时,下一个readyRead() 会被送达!我将调试语句放在myObject->Read() 的开头和结尾。他们确认,开始调试被一次又一次地调用。断点也是如此。
当接收到太多数据时,会创建一个包含太多Read()s 的递归堆栈帧。它要么减慢应用程序 GUI 的速度,要么崩溃。
通常,当客户端尝试将 ACK 作为myObject->Read() 的一部分发送时,就会发生这种递归。在此期间,readyRead() 被偶然发出信号并得到服务。但是前一个信号的槽仍在处理中。
问题:
- 当插槽仍在中间时(单线程),Qt 框架是否可以在两者之间提供信号?
- 如何修复这种特定于套接字的场景?
注意:
- 默认情况下,对于单线程,Qt::ConnectionType 是DirectConnection。我也试过QueuedConnection,但结果是一样的。
- myObject.Read() 相当复杂并且有许多其他的函数调用。如果这引起了问题,那么让我知道我应该寻找什么。编写它的实际代码是不切实际的。
【问题讨论】:
-
如果
myObject->Read()在您已经在其中时被调用,则很可能在某个时候您已经控制了事件循环。可以加一下函数的代码吗? -
@BenjaminT,在
Read()方法中有很多与Qt 无关的东西,而是核心功能。编写该代码是不切实际的,因为其中有几种方法。但是,当插槽仍在执行时,事件循环如何控制?你能建议,这在哪些方面是可能的。也许我可以试试看那些。 -
@SamuraiJack,感谢您提供的链接帖子。我试过了,但似乎
DirectConnection和QueuedConnection都会导致相同的行为。有什么东西会导致这个问题吗?请同时查看更新后的 Qn。 -
@iammilind:正如你所说,你在 myObject.Read() 中有很多函数调用,你可以使用 QtConcurrent::run 函数。它允许您异步运行函数。链接 - doc.qt.io/qt-4.8/qtconcurrentrun.html
标签: c++ qt sockets qt-signals qt-slot