在一个线程内进行的赋值在另一个线程中不可见

时间:2016-05-19 17:24:14

标签: c++ multithreading

我试图通过std::condition_variable和bool condition触发执行工作线程。如果condition为真,则工作人员等待通知并开始工作。工作condition设置为false后。另外还有一个互斥的同步器。

在主线程中,循环检查condition是否为false,如果是condition设置为true并且通知了condition_variable。

运行此代码时,我预计输出将会发送垃圾邮件" 醒来正在工作,但它只执行一次,因为conditionthread_function()的分配在某些方面是不可见的主线程/在工作线程内丢失。输出说,在赋值后它是错误的,当使用调试器进行调整时,它在赋值后为假,但是当主线程中的if被评估时,它再次为真。

我错过了什么吗?

我在VS2013和VS2012中尝试了这个,我尝试用bool替换std::atomic_bool,但这也没有帮助。

#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>
#include <atomic>

bool condition;
std::mutex condition_mutex;
std::condition_variable cv;

void thread_function() {
    while (true) {
        std::unique_lock<std::mutex> lock(condition_mutex);
        cv.wait(lock);
        std::cout << "woke up\n";
        if (condition) {
            // do stuff
            std::cout << "thread working\n";
            condition = false;
            std::cout << "thread: " << (condition ? "true" : "false") << "\n";
        }
    }
}

int main() {
    condition = false;
    std::thread t(&thread_function);

    while (true) {
        std::unique_lock<std::mutex> lock(condition_mutex);
//        std::cout << "main: " << (condition ? "true" : "false") << "\n";
        if (!condition) {
            condition = true;
            cv.notify_one();
        }
    }    
    return 0;
}

2 个答案:

答案 0 :(得分:1)

你应该把锁放在while循环之外:

void thread_function() {
    std::unique_lock<std::mutex> lock(condition_mutex);
    while (true) {
        cv.wait(lock);
        std::cout << "woke up\n";
        if (condition) {
            // do stuff
            std::cout << "thread working\n";
            condition = false;
            std::cout << "thread: " << (condition ? "true" : "false") << "\n";
        }
    }
}

重新进入循环时,线程函数很快失去锁定。这允许主线程在没有人等待时调用cv.notify_one()

答案 1 :(得分:1)

等待的规范方法包括测试条件,这将解决您的问题:

while (!condition) cv.wait(lock);

请参阅http://en.cppreference.com/w/cpp/thread/condition_variable/wait