我正试图了解Qt的整个内部过程,以及当我使用不同的线程时它是如何工作的。
正如我所理解的(谷歌和探索Qt源代码),如下:
- 每个线程都有一个本地"未决事件列表"和一个本地事件循环(如果我调用
exec
)与该列表交互。 -
QCoreApplication::postEvent(obj, e)
将对(obj, e)
添加到obj
线程的"待挂事件列表"中。 - 每个线程都有一个本地"事件分派器"(
QAbstractEventDispatcher
专门化),其目的是读取系统事件。因此,它存在QEventDispatchWin
,QEventDispatchUnix
,QEventDispatchSymbian
等等,用于不同的平台。对于gui
事件,Qt也有QEventDispatchX11
(从QEventDispatchUnix
继承),S60
(从Symbian
)等。
考虑到所有这些,exec
调用的工作方式如下:
Thread's `exec`:
├ create a QEventLoop object.
└ call QEventLoop.exec()
└ call repeatedly eventDispatcher's processEvents with WaitForMoreEvents flag.
├ call to QCoreApplication::sendPostedEvents
├ while (!pending system events)
│ ├ read system event
│ ├ create an appropiate QEvent e and detect its target QObject o.
│ └ call to QCoreApplication::sendSpontaneousEvent(o, e)
└ call to QCoreApplication::sendPostedEvents
(for new generated user events in the previous step).
如果quit
或exit
被调用,它结束当前的processEvents
调用,exec
返回传递给exit
的值。
需要考虑的几点:
- 系统事件永远不会推送/发布:当它们从系统生成并转换为QEvents时,它们直接发送到目标对象。
- 目标对象成员函数(
o.event()
)在processEvent
发生的线程中被调用。
现在,怀疑:
- 既然
postEvent
是一个静态的线程安全函数,QCoreApplication在这个事件处理系统中扮演什么角色?和QApplication吗?为什么必须尽快创建它们?为什么QApplication/QCoreApplication是强制获取系统事件,如果每个线程都有自己的"事件调度器"?欢迎对我的假设进行任何更正。
在回应你的第二个问题,"为什么QApplication/QCoreApplication是强制性的获得系统事件,如果每个线程都有自己的"事件调度程序"?"
4.8文档声明:
"注意QCoreApplication::exec()必须始终从主线程(执行main()的线程)调用,而不是从QThread调用。在GUI应用程序中,主线程也称为GUI线程,因为它是唯一允许执行GUI相关操作的线程。"
但是一般来说,你会发现提供的链接将QThreads描述为QObjects,它是线程的包装器。所以qthread,像其他qobject一样,需要与QCoreApplication进行交互,以便协调通知/事件,例如,当线程完成时。
http://qt-project.org/forums/viewthread/14806在Maya的文章中,她提供了一个任务分配给QThread而不是在[即使用信号/插槽并且不重载run()方法]中定义的例子。通过这种方式,您可以清楚地看到QCoreApplication提供的主事件循环仍然起着至关重要的作用。
你可能已经知道,在这个站点上已经有大量的关于QThreads的讨论——Qt4的文档记录非常充分……Qt5 =(