【问题标题】:When would someone define a std::vector as thread_local? [duplicate]什么时候有人将 std::vector 定义为 thread_local? [复制]
【发布时间】:2016-11-11 12:58:21
【问题描述】:

std::vector 声明为thread_local 有什么好处吗? 喜欢

static unique_ptr<std::vector<ObjectA>> vecVariable;

std::vector 声明为thread_local 不会使其操作像pop_back()erase() 同步。

就像在每个 STL 容器中一样,如果有一个线程修改容器,则不会有并发线程读取或写入同一个容器,所以我不能在 vector 对象上执行 erase()pop_back()并发/多线程环境。

即使我将向量声明为thread_local,我的代码也会在其中一个操作中崩溃。我知道我可能需要在锁定状态下执行这些操作,但我只是想了解何时有人将 std::vector 定义为 thread_local

【问题讨论】:

  • 同时他们将任何变量定义为 thread_local - 当他们每个线程都有自己的实例时。

标签: c++ multithreading vector stdvector thread-local


【解决方案1】:

thread_local 不用于同步。它是一个存储持续时间说明符 (http://en.cppreference.com/w/cpp/language/storage_duration)

举个例子:

#include <iostream>
#include <vector>
#include <thread>

thread_local std::vector<int> v;

void func()
{
  v.push_back(5);
  std::cout<< "t: "<< v.size() << std::endl;
}

int main() 
{
    v.push_back(3);
    v.push_back(5);
    std::thread t1(func);
    std::thread t2(func);
    std::cout<< "m: "<< v.size() << std::endl;
    t1.join();
    t2.join();
}

输出:

m: 2
t: 1
t: 1

thread_local 所做的是为每个线程创建一个不同的向量。在示例中,您可以看到主线程中的 v 有 2 个元素,而其他线程中的向量 v 每个只有 1 个元素。

发生的情况是,当创建一个新线程时,程序还将仅为该线程创建一个新向量。当线程结束时,向量也会被销毁。

【讨论】:

    【解决方案2】:

    thread_local 使对象拥有线程存储,这意味着每个线程将拥有自己独立的对象实例。它不会以任何方式影响对象的线程安全,正如您似乎建议您认为的那样。

    如果您希望每个线程都有自己的变量实例,您可以声明一个vector 变量或任何其他变量thread_local。如果您希望能够同时访问单个对象,解决方案不是将其声明为thread_local,而是使用线程安全数据类型或适当的同步原语(例如,通过锁定和解锁std::mutex)。

    【讨论】:

    • @GillBates 每个线程可以访问属于其他线程的副本,如果它可以通过其他方式获得对它们的引用。该名称指的是不同线程中的不同对象并不意味着线程安全。
    • 当然可以通过地址传递或全局引用。我说的是使用名称并且仅使用名称的情况。
    • 正如我所说,当通过它的名字访问这个向量中的元素时,首先不需要关心线程安全,例如vector[0]。关键字本身不会带来任何同步,但如果线程不依赖其他线程来填充或修改此容器,则通过正确使用可以避免线程之间的数据竞争。
    • 确实,我会清除该评论以避免这种误解。
    • @GillBates 我认为我们可以同意,如果仅通过该变量访问通过thread_local 变量访问的对象的线程安全性,则无需担心,但我认为这是一个拉伸说变量上的thread_local会影响变量声明的对象的线程安全;如果对象仅通过变量访问,它可能使线程安全成为非问题,如上所述,但这与使其成为线程安全不同 - 它只是使它成为它不需要 是线程安全的。
    猜你喜欢
    • 2017-07-24
    • 1970-01-01
    • 1970-01-01
    • 2017-12-21
    • 2017-05-22
    • 2011-10-01
    • 2011-03-11
    • 1970-01-01
    • 2012-11-25
    相关资源
    最近更新 更多