gpt4 book ai didi

qt - 为什么要避免QEventLoops的嵌套?

转载 作者:行者123 更新时间:2023-12-04 07:19:24 26 4
gpt4 key购买 nike

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

QEventLoop is for nesting event Loops... Avoid it if you can because it creates a number of problems: things might reenter, new activations of sockets or timers that you were not expecting.



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

最佳答案

  • 嵌套事件循环会占用1-2kb的堆栈。这是典型的32kb L1高速缓存CPU占用的L1数据高速缓存的5%。
  • 它具有重新输入调用堆栈中已经存在的任何代码的能力。不能保证该代码中的任何一个都是可重入的。我说的是您的代码,而不是Qt的代码。它可以重新输入启动此事件循环的代码,除非您明确控制此递归,否则无法保证最终不会耗尽堆栈空间。
  • 在当前的Qt中,由于长期存在的API错误或平台不足,在两个地方,您必须使用嵌套的exec:QDrag和平台文件对话框(在某些平台上)。您根本不需要在其他任何地方使用它。对于非平台模式对话框,不需要嵌套事件循环。
  • 重新进入事件循环通常是由于编写伪同步代码而引起的,其中有人哀叹所谓的yield()缺失(现在co_yieldco_await已在C++中登陆!),将头埋在沙子里,而是使用exec()。这样的代码通常最终变成几乎不美味的意大利面,并且是不必要的。

    对于现代C++,使用C++ 20协程是值得的。周围有一些Qt-based experiments,易于构建。

    有Qt native 的可实现协程的实现:Skycoder42/QtCoroutings-最近的项目,和较旧的ckamm/qt-coroutine。我不确定后面的代码有多新鲜。看起来这一切都在某个时候起作用。

    干净地编写没有协程的异步代码通常是通过状态机完成的,请参见this answer为例,以及QP framework不同于QStateMachine的实现。

  • 个人轶事:我迫不及待地希望C++协程变得可以投入生产,现在我用golang编写异步通信代码,并将其静态链接到Qt应用程序中。效果很好,垃圾回收器不引人注意,并且代码比带有协程的C++更易于读写。我有很多使用C++协程TS编写的代码,但是将它们全部移到了golang上,我并不后悔。

    关于qt - 为什么要避免QEventLoops的嵌套?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35561182/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com