Skip to content
正常

QThread 源码索引

本索引收录 Qt 6.9.1 源码中 QThread 的已验证证据。QObject 的线程亲和(thread()/moveToThread)在 对象树所有权 已有覆盖,本文件聚焦 QThread 本身的 lifecycle。事件循环 QEventLoop 的内部见 事件循环

QThread 身份与线程亲和根源

源码文件:qtbase/src/corelib/thread/qthread.h / kernel/qobject.cpp / kernel/qobject_p.h

论点行号原文摘要解读
QThread 继承 QObject(管理者非线程本身)qthread.h:27-29class Q_CORE_EXPORT QThread : public QObject { Q_OBJECTQThread 实例本身是个 QObject,住在创建它的线程(通常主线程),管理的那个新线程是另一回事。
QObject 构造从当前线程绑 threadDataqobject.cpp:946-955auto threadData = (parent && !parent->thread()) ? parent->d_func()->threadData.loadRelaxed() : QThreadData::current(); threadData->ref(); d->threadData.storeRelaxed(threadData);「在哪个线程 new 这 QObject,它就属于哪个线程」。三目:parent 存在且 parent 无亲和性时继承 parent 的 TD,否则取当前线程。thread() 读它(qobject.cpp:1610)。

run/exec 双核

源码文件:qtbase/src/corelib/thread/qthread.cpp

论点行号原文摘要解读
run 虚函数默认调 execqthread.h:112, qthread.cpp:778virtual void run(); / void QThread::run() { (void) exec(); }子类重写 run 不调 exec 就没事件循环——worker 模式 vs subclass run 模式分水岭。
exec 栈上构造 QEventLoopqthread.cpp:644-665QEventLoop eventLoop; int returnCode = eventLoop.exec();非 virtual 不能重写。进入前清 quitNow,查 exited 决定是否直接返回旧 retcode。

start→平台创建→入口

源码文件:qtbase/src/corelib/thread/qthread_unix.cpp / qthread_win.cpp

论点行号原文摘要解读
start 经 pthread_create / CreateThreadunix:847, win:358pthread_create(&threadId, &attr, QThreadPrivate::start, this) / CreateThread(..., QThreadPrivate::start, this, CREATE_SUSPENDED, ...)Win 用 CREATE_SUSPENDED 挂起创建、设完优先级再 ResumeThread。失败 threadState 回退 NotStarted。
QThreadPrivate::start 平台入口流程unix:382-441, win:143-191set_thread_data(data); data->ensureEventDispatcher(); emit thr->started(QPrivateSignal()); thr->run(); finish()两平台基本一致。Unix 用 pthread_cleanup_push/pop 保证 pthread_cancel 也调 finish;入口先 DISABLE cancel、emit started 后才 ENABLE + pthread_testcancel。

QThreadData 线程身份包

源码文件:qtbase/src/corelib/thread/qthread_p.h / qthread.cpp

论点行号原文摘要解读
QThreadData 结构(每线程一个)qthread_p.h:302-376QStack<QEventLoop *> eventLoops; QPostEventList postEventList; QAtomicPointer<QThread> thread; QAtomicPointer<void> threadId; QAtomicPointer<QAbstractEventDispatcher> eventDispatcher; QList<void *> tls; bool quitNow; bool canWait; bool isAdopted;eventLoops 栈支持嵌套 exec;postEventList 优先级排序;isAdopted 区分 Qt 创建 vs 外部收养。还含 loopLevel/scopeLevel/requiresCoreApplication。
currentThread 经 thread-localqthread.cpp:387-392QThreadData *data = QThreadData::current(); return data->thread.loadAcquire();QThreadData::current 先查 thread-local,查不到就 createCurrentThreadData + new QAdoptedThread(无 Qt 的外部线程也能用)。

信号时机

源码文件:qtbase/src/corelib/thread/qthread_unix.cpp / qthread_win.cpp / qthread.cpp

论点行号原文摘要解读
started 在新线程 run 之前发unix:429, win:185emit thr->started(QThread::QPrivateSignal()); ... thr->run();QPrivateSignal 禁外部手动 emit。新线程发,cross-thread 槽可能延迟到 run 已开始后才到。
finished 在 finish() 里 Finishing 后立刻发unix:443-461, win:237-249d->threadState = Finishing; emit thr->finished(QPrivateSignal()); QCoreApplication::sendPostedEvents(nullptr, DeferredDelete);紧跟 DeferredDelete——让 deleteLater 对象在事件循环已停后仍能清。注意:terminate() 路径下 finished 发送线程 undefined(qthread.cpp:353-354 \note)。

退出、中断、terminate

源码文件:qtbase/src/corelib/thread/qthread.cpp / qthread_p.h

论点行号原文摘要解读
quit/exit 设标志 + 遍历退 eventLoopsqthread.cpp:741-752d->exited=true; d->returnCode=returnCode; d->data->quitNow=true; for (...) eventLoop->exit(returnCode);支持嵌套 exec。不真停线程,run 没调 exec 则无效。
requestInterruption 协作式(atomic bool)qthread.cpp:1275-1286, qthread_p.h:199if (d->threadId() == theMainThreadId.loadAcquire()) { qWarning(...); return; } ... d->interruptionRequested.store(true, relaxed);不碰调度,靠 run() 自己 poll isInterruptionRequested()。主线程拒绝判定基于 theMainThreadId(QCoreApplication 创建线程,无 GUI 也生效)。isInterruptionRequested fast/slow 双路径。
terminate 危险 + 平台差异unix:868-899, win:415-428, qthread.cpp:904Unix if (d->terminated) return; pthread_cancel(...)(防 ABA)/ Win TerminateThread(d->handle, 0); d->finish(false) / Android 空实现文档 \warning 危险且不鼓励。Win 的 finish(false) lockAnyway=false 因可能从 wait/terminate 已持锁。

wait / setPriority

源码文件:qtbase/src/corelib/thread/qthread.cpp / qthread_unix.cpp / qthread_win.cpp

论点行号原文摘要解读
wait 三门 + 平台 joinqthread.cpp:950-962, unix:914, win:430NotStarted/Finished 直返 / 自等自 qWarning / 否则 d->wait(locker, deadline)Unix pthread_clockjoin_np / pthread_timedjoin_np,Win WaitForSingleObject。
Priority 7 档 + setPriority 守卫qthread.h:40-52, qthread.cpp:802-815enum Priority { IdlePriority, ..., TimeCriticalPriority, InheritPriority } / setPriority if (priority == InheritPriority) return; if (threadState != Running) return;InheritPriority 是 start 参数语义不能运行中改;非 Running 拒绝。

QThread::create 现代 lambda 工厂

源码文件:qtbase/src/corelib/thread/qthread.h / qthread.cpp

论点行号原文摘要解读
create 经 std::async(deferred) + QThreadCreateThread 子类qthread.h:84-85+131-144, qthread.cpp:1347-1369[[nodiscard]] static QThread *create(Function &&f, Args &&... args) / createThreadImpl(std::async(std::launch::deferred, ...)) / QThreadCreateThread::run() { m_future.get(); } / ~QThreadCreateThread() { requestInterruption(); quit(); wait(); }lambda 经 deferred 包成 future,子类 run 调 get() 触发在新线程执行。[[nodiscard]] 禁忽略,析构自动安全收尾。start 只能调一次。

AwesomeQt v0.3.0-13-g31f4d47 · 31f4d47 · 2026-09-22 · CHECKED-BY: CI