【问题标题】:Do thread_local variables need to be locked using a mutex?thread_local 变量是否需要使用互斥锁锁定?
【发布时间】:2015-10-31 17:40:51
【问题描述】:

我将thread_local 变量视为每个线程的私有变量,只是名称相同。但是我发现的所有示例都使用mutex 变量在访问它时锁定thread_local 变量。这让我很困惑。如果thread_local对每个线程都是私有的,那么并发问题就不用管了,还是我对“私有”的想法的承认有误?

示例取自here:

#include <iostream>
#include <string>
#include <thread>
#include <mutex>

thread_local unsigned int rage = 1; 
std::mutex cout_mutex;

void increase_rage(const std::string& thread_name)
{
    ++rage;
    std::lock_guard<std::mutex> lock(cout_mutex);
    std::cout << "Rage counter for " << thread_name << ": " << rage << '\n';
}

int main()
{
    std::thread a(increase_rage, "a"), b(increase_rage, "b");
    increase_rage("main");

    a.join();
    b.join();
}

在这种情况下,是否需要锁定thread_local变量?

【问题讨论】:

  • 哪个例子?如果你展示它,我们可能会告诉你为什么它使用互斥锁,可能有不同的原因。
  • @RaphaelMiedl 我得到了一个:stackoverflow.com/a/15698197/2269707
  • mutex 只是通过std::cout 同步输出(std::cout 不是线程安全的,可以交错输出),顾名思义,它与线程局部变量。您可以通过输出看到 thread_local 变量是完全不同的。
  • 互斥体也被锁定之后 ++rage,thread_local 变量根本没有受到保护,也不需要。
  • 是的,thread_local 变量不需要同步。在您的示例中,互斥锁绝对只对 cout 是必需的。

标签: c++ multithreading


【解决方案1】:

如果你获取一个指向thread_local对象的指针,并将指针传递给另一个线程,在某种程度上,另一个线程仍然可以使用指针访问原始线程的thread_local对象(直到原始线程终止,之后这个成为未定义的行为)。

因此,如果这可能发生在您的应用程序中,您仍然需要安排互斥保护或等效的东西,以便以线程安全的方式访问 thread_local 对象。

【讨论】:

    【解决方案2】:

    命名thread_local变量私有变量有点可惜。

    thread_local 声明的变量归其thread 所有,其他threads 不能访问,除非所有者thread(出于某种原因)给他们一个指向该变量的指针。 thread_local 变量在其线程的所有函数之间共享;即它有它的生命周期。如果构造了thread_local 变量,它将在其thread 退出时被销毁。

    thread_local 变量可以是静态的,在这种情况下,应注意确保程序按预期执行。我不会讨论这个,因为它不是问题的一部分。

    正如 cmets 中所指出的,您的示例中的 mutex 不适用于数据竞争条件。它是同步控制台输出:mutex 被称为cout_mutex - 自我解释。

    【讨论】:

      猜你喜欢
      • 2011-09-06
      • 2011-12-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-30
      相关资源
      最近更新 更多