c++ - 在线程内进行的分配在另一个线程中不可见

标签 c++ multithreading

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

在主线程中,循环检查 condition 是否为假,如果是,则将 condition 设置为真并通知 condition_variable。

当运行这段代码时,我预计输出会“垃圾”唤醒工作,但它只执行一次,因为不知何故分配给 condition in thread_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;
}

最佳答案

您应该将锁放在 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()

关于c++ - 在线程内进行的分配在另一个线程中不可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37330145/

相关文章:

c++ - omp_set_max_active_levels() 和函数调用

multithreading - FreeThreadedDOMDocument,Neutral Apartments和Free-threaded Marshaler

c++ - 检查一张图片是否是另一张图片的移位

c++ - 如何访问和管理 block 存储的数据

android - 服务、线程和进程

Python Flask 关闭事件处理程序

C#线程处理消息队列

c++ - 为什么使用 typeid 关键字是糟糕的设计?

c++ - 将基本数据类型封装到类中

C++ Armadillo 没有正确解决条件不佳的矩阵