在std :: thread或pthread_create中创建的QObject的QThreadData是什么?

时间:2019-07-16 15:57:09

标签: c++ multithreading qt

无论何时创建QObject,QT都会在其构造函数中将QThreadData分配给QObject。除其他外,该QThreadData然后用于检查与QObject相关的事件循环的存在。

使用Qt线程工具(例如QThread或通过单线程应用程序中的QCoreApplication隐式)时,Qt会为QThreadData分配有意义的值,并且一切都会按预期进行。

但是,以下源代码暗示在手动系统接口线程工具中创建的QObject(例如在pthread_create或std :: thread中)将仅从最后一个QT线程工具调用中复制最后一个QThreadData :(代码从/qt5/qtbase/src/corelib/thread/qthread_unix.cpp复制并定义了HAVE_TLS)

// Utility functions for getting, setting and clearing thread specific data.
static QThreadData *get_thread_data()
{
#ifdef HAVE_TLS
    return currentThreadData;
#else
    pthread_once(&current_thread_data_once, create_current_thread_data_key);
    return reinterpret_cast<QThreadData *>(pthread_getspecific(current_thread_data_key));
#endif
}

在上面的代码示例中,“ currentThreadData”是一个静态变量,由QT在任何QT线程工具调用(例如QThread)期间预先设置。

我的问题是:

  1. 我的理解正确吗?
  2. 如果是,这是否会导致在完全错误的eventLoop(与QT设置的最后一个“ currentThreadData”相关联的事件循环)中调用到此QObject插槽的QueuedConnection。
  3. 如果否,QT如何理解在pthread_create中创建的Qobject与任何事件循环都不相关?

(请注意,我始终假设QObject的父对象设置为NULL。因为当为QObject设置父对象时,会直接从该父对象复制QThreadData,并且一切都会再次正常工作。)

1 个答案:

答案 0 :(得分:1)

我不确定我是否完全理解这个问题。但是,当您说......

  

“ currentThreadData”是一个静态变量,之前由   在任何QT线程工具调用(例如QThread)期间进行QT。

...您遗漏了一个要点:currentThreadData也被声明为thread local

在代码库中,我正在查看(Qt 5.13.0)...

static __thread QThreadData *currentThreadData = 0;

__thread是特定于编译器的扩展,它基本上提供与c++11关键字thread_local相同的线程本地存储持续时间。

因此,一个线程所见的currentThreadData变量与其他任何线程所见的currentThreadData变量完全分开。