如何使类静态变量线程安全

时间:2016-12-16 17:25:05

标签: c++ multithreading

我有一个类似的课程:

class Test
{
private:
    Test() {}
    static bool is_done;
    static void ThreadFunction();
public:
    static void DoSomething();
}


bool Test::is_done = true;

void Test::DoSomething()
{
    std::thread t_thread(Test::ThreadFunction);

    while (true) {
        if (is_done) {
            //do something else
            is_done = false;
        }

        if (/*something happened*/) { break; }
    }

    // Finish thread.
    t_thread.join();
}

void Test::ThreadFunction()
{
    while (true) {
        if (/*something happened*/) {
            is_done = true;
        }
    }
}

在主要我然后只需调用Test :: DoSomething();在这种情况下,变量'is_done'是否安全?如果不是我怎么能安全阅读呢?

3 个答案:

答案 0 :(得分:7)

  

在这种情况下,全局变量'is_done'是否安全线程?

没有。 static并不意味着线程安全。

  

如果不是我怎么能安全阅读呢?

您应该使用std::atomic<bool>

class Test
{
private:
    Test() {}
    static std::atomic<bool> is_done;
    static void ThreadFunction();
public:
    static void DoSomething();
}

std::atomic<bool> Test::is_done{true};

答案 1 :(得分:2)

我还没有发表评论,但您是否尝试过使用原子?

e.g。 std::atomic<bool>

答案 2 :(得分:2)

如果类型为TriviallyCopyable,那么您可以使用std::atomic之类的

static std::atomic<bool> is_done;

如果您的类型不是TriviallyCopyable,那么您可以使用std::mutex

不要将std::atomic操作优化掉。如果您有类似

的内容
static std::atomic<bool> is_done;
...
is_done = true;
is_done = false;

编译器可以删除is_done = true;关于此问题,请参阅JF Bastien的“No Sane Compiler Would Optimize Atomics"