c++ - 需要对条件变量寻求的互斥保护(原子)赋值吗?

标签 c++ multithreading boost-thread

我了解如何使用条件变量(此构造的名称很糟糕,IMO,因为 cv 对象既不是变量也不表示条件)。所以我有一对线程,canonically使用 Boost.Thread 设置为:

bool awake = false;
boost::mutex sync;
boost::condition_variable cv;
void thread1()
{
    boost::unique_lock<boost::mutex> lock1(sync);
    while (!awake)
        cv.wait(lock1);
    lock1.unlock();    // this line actually not canonical, but why not?
    // proceed...
}
void thread2()
{
    //...
    boost::unique_lock<boost::mutex> lock2;
    awake = true;
    lock2.unlock();
    cv.notify_all();
}

我的问题是:thread2 真的需要保护分配给 awake 吗?在我看来,notify_all() 调用应该足够了。如果被操作和检查的数据不仅仅是一个简单的“可以继续”标志,我会在互斥锁中看到该值,但在这里它似乎有点过分了。

第二个问题是代码片段中提出的问题:为什么 Boost 文档没有显示在“处理数据”步骤之前解锁线程 1 中的锁?

编辑:也许我的问题真的是:是否有比 CV 更简洁的结构来实现这种等待?

最佳答案

does thread2 really need to be protecting the assignment to awake?

是的。从一个线程修改一个对象并在没有同步的情况下从另一个线程访问它会产生未定义的行为。即使它只是一个 bool

例如,在一些多处理器系统上,写入可能只影响本地内存;如果没有显式同步操作,其他线程可能永远看不到更改。

Why doesn't the Boost documentation show the lock in thread1 being unlocked before the "process data" step?

如果您在清除标志之前解锁了互斥量,那么您可能会错过另一个信号。

Is there a cleaner construct than a CV to implement this kind of wait?

在 Boost 和标准 C++ 库中,没有;条件变量足够灵活,可以处理任意共享状态,并且对于这种简单的情况不会特别复杂,因此没有特别需要更简单的东西。

更一般地说,您可以使用信号量或管道在线程之间发送简单信号。

关于c++ - 需要对条件变量寻求的互斥保护(原子)赋值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11547320/

相关文章:

c++ - 我的 bad_alloc 从哪里来?

c++ - 使用非 constexpr 对象的静态 constexpr 成员变量作为模板参数

multithreading - 您如何实现软件事务内存?

c++ - String getline(cin,variable) 函数正在跳过一些代码行

c++ - 预编译 header 和 MSBuild

c++ - 是否有其他方法可以使用条件变量捕获可能遗漏的信号?

java - 如何使用 CyclingBarrier 同步线程并保留其执行顺序?

c++ - 多线程性能

c++ - mutex.timed_lock(duration) 和 boost::timed_mutex::scoped_lock 之间的区别 scoped_lock(mutex, duration)

C++ getter/setter、互斥量、细粒度锁定