在他的Qt event loop, networking and I/O API talk中,Thiago Macieira提到应该避免QEventLoop
的嵌套:
QEventLoop用于嵌套事件循环...如果可以,请避免使用它,因为它会产生许多问题:事情可能会重新进入,新的套接字或定时器激活是你不期望的。
任何人都可以扩展他所指的内容吗?我维护了许多代码,这些代码使用模式对话框,在调用exec()
时内部嵌套一个新的事件循环,所以我非常有兴趣知道这可能会导致什么样的问题。
答案 0 :(得分:8)
嵌套的事件循环会花费1-2kb的堆栈。
它具有重新输入调用堆栈上已有代码的能力。无法保证任何代码都是可重入的。我在谈论你的代码,而不是Qt的代码。
在当前的Qt中,有两个地方,由于长期存在的API错误或平台不足,您必须使用嵌套的exec
:QDrag
和平台文件对话框(在某些地方)平台)。您根本不需要在其他任何地方使用它。您不需要非平台模式对话框的嵌套事件循环。
重新进入事件循环通常是因为编写伪同步代码而导致缺少yield()
,将头埋在沙中并使用exec()
。这样的代码通常最终成为意大利面并且是不必要的。干净地编写异步代码通常通过状态机完成,有关示例,请参阅this answer,QP 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。
我根据经验说话,这通常导致我的代码崩溃。