QThreadData *QThreadData::current(bool createIfNecessary)
{
QThreadData *data = get_thread_data();
if (!data && createIfNecessary) {
data = new QThreadData;
QT_TRY {
set_thread_data(data);
data->thread = new QAdoptedThread(data);
} QT_CATCH(...) {
clear_thread_data();
data->deref();
data = 0;
QT_RETHROW;
}
data->deref();
data->isAdopted = true;
data->threadId.store(to_HANDLE(pthread_self()));
if (!QCoreApplicationPrivate::theMainThread)
QCoreApplicationPrivate::theMainThread = data->thread.load();
}
return data;
}
● 在使用new QThreadData创建data时,其引用计数默认为1,然后通过set_thread_data设置为线程本地存储
● 关键就是new QAdoptedThread(data)会将data的引用计数增加到2,因为QAdoptedThread最终会调用QObject的构造函数QObject(QObjectPrivate &dd, QObject *parent)
设置主线程为QAdoptedThread,创建的对象如果没有指定父对象,则对象的线程数据threadData为主线程的线程数据。QAdoptedThread线程是不会运行的
void QAdoptedThread::run()
{
// this function should never be called
qFatal("QAdoptedThread::run(): Internal error, this implementation should never be called.");
}
QObject::QObject(QObjectPrivate &dd, QObject *parent)
: d_ptr(&dd)
{
Q_D(QObject);
d_ptr->q_ptr = this;
d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
d->threadData->ref();
if (parent) {
QT_TRY {
if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
parent = 0;
if (d->isWidget) {
if (parent) {
d->parent = parent;
d->parent->d_func()->children.append(this);
}
// no events sent here, this is done at the end of the QWidget constructor
} else {
setParent(parent);
}
} QT_CATCH(...) {
d->threadData->deref();
QT_RETHROW;
}
}
#if QT_VERSION < 0x60000
qt_addObject(this);
#endif
if (Q_UNLIKELY(qtHookData[QHooks::AddQObject]))
reinterpret_cast<QHooks::AddQObjectCallback>(qtHookData[QHooks::AddQObject])(this);
Q_TRACE(QObject_ctor, this);
}
因为parent为nullptr,所以会再次调用QThreadData::current(),而此时调用get_thread_data获取得到的data不为空,该值也是第一次调用QThreadData::current()时分配出来的data
将其赋值给threadData,然后调用ref()会将其引用计数增加为2