为什么要避免嵌套QEventLoops?

时间:2016-02-22 18:33:12

标签: qt

在他的Qt event loop, networking and I/O API talk中,Thiago Macieira提到应该避免QEventLoop的嵌套:

  

QEventLoop用于嵌套事件循环...如果可以,请避免使用它,因为它会产生许多问题:事情可能会重新进入,新的套接字或定时器激活是你不期望的。

任何人都可以扩展他所指的内容吗?我维护了许多代码,这些代码使用模式对话框,在调用exec()时内部嵌套一个新的事件循环,所以我非常有兴趣知道这可能会导致什么样的问题。

2 个答案:

答案 0 :(得分:8)

  1. 嵌套的事件循环会花费1-2kb的堆栈。

  2. 它具有重新输入调用堆栈上已有代码的能力。无法保证任何代码都是可重入的。我在谈论你的代码,而不是Qt的代码。

  3. 在当前的Qt中,有两个地方,由于长期存在的API错误或平台不足,您必须使用嵌套的execQDrag和平台文件对话框(在某些地方)平台)。您根本不需要在其他任何地方使用它。您不需要非平台模式对话框的嵌套事件循环。

  4. 重新进入事件循环通常是因为编写伪同步代码而导致缺少yield(),将头埋在沙中并使用exec()。这样的代码通常最终成为意大利面并且是不必要的。干净地编写异步代码通常通过状态机完成,有关示例,请参阅this answerQP framework执行与QStateMachine不同的实现。

答案 1 :(得分:0)

嵌套的事件循环将导致排序反转。 (至少在qt4上)

让我们说你发生了以下一系列事情

enqueued in outer loop: 1,2,3
processing 1 => spawn inner loop
enqueue 4 in inner loop
processing 4
exit inner loop
processing 2

所以你看到处理顺序是:1,4,2,3。

我根据经验说话,这通常导致我的代码崩溃。