【问题标题】:QThreadStorage vs C++11 thread_localQThreadStorage vs C++11 thread_local
【发布时间】:2018-06-14 10:00:40
【问题描述】:

正如标题所示:有什么区别。我知道QThreadStorage 早在thread_local 关键字之前就存在了,这可能就是它首先存在的原因——但问题仍然存在:它们在这两者之间所做的事情是否有任何显着差异(除了QThreadStorage)。

我假设静态变量的正常用例 - 因为使用 QThreadStorage 作为非静态变量是可能的,但不建议这样做。

static thread_local int a;
// vs
static QThreadStorage<int> b;

【问题讨论】:

    标签: qt c++11 thread-local-storage


    【解决方案1】:

    好吧,由于 Qt 是开源的,您基本上可以从 Qt 源代码中找出答案。我目前正在查看 5.9,这里有一些我认为很重要的东西:

    1) 查看qthreadstorage.cpp,get/set 方法的开头都有这个块:

    QThreadData *data = QThreadData::current();
    if (!data) {
        qWarning("QThreadStorage::set: QThreadStorage can only be used with threads started with QThread");
        return 0;
    }
    

    所以(也许这已经改变/将会改变)你不能将QThreadStorageQThread 以外的任何东西混合,而thread_local 关键字没有类似的限制。

    2) 在thread_local 上引用cppreference

    线程存储持续时间。对象在线程开始时分配,在线程结束时释放。

    查看qthreadstorage.cppQThreadStorage 类实际上不包含T 的任何存储空间,实际存储空间是在第一次 get 调用时分配的:

    QVector<void *> &tls = data->tls;
    if (tls.size() <= id)
        tls.resize(id + 1);
    void **v = &tls[id];
    

    所以这意味着这两者之间的生命周期完全不同 - 使用 QThreadStorage 您实际上拥有更多控制权,因为您创建对象并使用 setter 设置它,或者默认使用 getter 初始化。例如。如果该类型的 ctor 可以抛出,QThreadStorage 你可以抓住它,thread_local 我什至不确定。

    我认为这两个足够重要,不会再深入了。

    【讨论】:

    • thread_local 实际上是 static 持续时间,但在线程的上下文中。
    • @Mgetz - 是的,我想这是第二点的更简单的方法。
    • 显然,还有一个区别:在 Windows 上,thread_local 不能是导出符号 - 但 QThreadStorage 可以(参见 stackoverflow.com/questions/32034857/…
    猜你喜欢
    • 2019-11-20
    • 2019-01-27
    • 1970-01-01
    • 1970-01-01
    • 2014-12-20
    • 2014-05-12
    • 2013-10-04
    • 1970-01-01
    • 2018-03-11
    相关资源
    最近更新 更多