C++:互斥锁从通知程序到服务员的传递是无缝的吗?

标签 c++ multithreading mutex condition-variable

在多线程环境下,我们有以下两个函数:

std::mutex mtx;    
std::condition_variable cv;

void waiter()
{
   std::unique_lock<std::mutex> lck(mtx);
   //...
   cv.wait(lck);
   //...
}

void notifier()
{
   std::unique_lock<std::mutex> lck(mtx);
   //...
   cv.notify_one();
}

假设服务员先执行,然后等待condition_variable。然后通知程序执行并通知服务员。等待者在通知者释放后尝试重新获取互斥体。

问题: 是否有可能其他线程在通知程序释放互斥量之后但在等待者获取它之前就锁定了互斥量?如果是,必须做些什么才能避免这种情况发生?如果是,我也不明白condition_variable 的用途。目的应该是阻塞线程直到满足某些条件。但是,如果在条件满足并且线程被唤醒后,有可能再次条件不满足,那又有什么意义呢?

最佳答案

Is it possible that some other thread locks the mutex right after the notifier has released it but still before the waiter gets it?

是的。

If yes, what has to be done so that this cannot happen?

没有。

And if yes, I also don't understand the purpose of condition_variable. The purpose should be to block a thread until some condition is fulfilled. But if, after the condition is fulfilled and the thread has been woken up, there is the chance that again the condition is not fulfilled, what's the point?

这就更复杂了。如果根本没有通知条件变量,则线程可以被唤醒。这称为虚假唤醒 (doc)。

条件变量的要点是阻塞一个线程,直到其他线程通知它。为了解决“当等待线程有机会执行时条件不满足”的问题,通常等待线程在循环中等待直到条件满足。标准库甚至有一个快捷方式,有一个 void wait( std::unique_lock<std::mutex>& lock, Predicate pred );。重载正是这样做的。查看doc .

关于C++:互斥锁从通知程序到服务员的传递是无缝的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40440712/

相关文章:

c++ - C++模板特化成员函数的定义

python - 在调用函数时如何防止 GUI 卡住? (PyQT4, Python3)

c - 一个简单的pthread变量共享

java - Log4j2 环境中单个软件组件的 Logger 对象

multithreading - 如何正确销毁pthread互斥锁

c++ - lldb如何检查互斥量的所有者?

无法使用 pthread_mutex_lock 同步超过 2 个线程

c++ - 像这样使用 `const char *` 返回字符串是否合法?

c++ - 在模板类中折叠指针?

c++ - Vim 不高亮某些单词