Qt多线程之QThreadData::current()理解

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)

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

你可能感兴趣的:(Qt,qt)