std::condition_variable 是不是真的在阻塞之前解锁了给定的 unique_lock 对象?
Posted
技术标签:
【中文标题】std::condition_variable 是不是真的在阻塞之前解锁了给定的 unique_lock 对象?【英文标题】:Does std::condition_variable really unlock the given unique_lock object before blocking?std::condition_variable 是否真的在阻塞之前解锁了给定的 unique_lock 对象? 【发布时间】:2020-10-20 19:44:14 【问题描述】:正如参考所说:1) Atomically unlocks lock, blocks the current executing thread, and...
我有以下代码:
#include <iostream>
#include <thread>
#include <condition_variable>
std::mutex mutex_;
std::condition_variable condVar;
std::unique_lock<std::mutex> lck(mutex_); //purposely global to check return of owns_lock() in main
void waitingForWork()
std::cout << "Before wait, lck.owns_lock() = " << lck.owns_lock() << '\n';
condVar.wait(lck);
std::cout << "After wait, lck.owns_lock() = " << lck.owns_lock() << '\n';
int main()
std::thread t1(waitingForWork);
std::this_thread::sleep_for(std::chrono::seconds(10));
std::cout << "In main, lck.owns_lock() = " << lck.owns_lock() << '\n';
condVar.notify_one();
t1.join();
return 0;
编译使用:g++ with c++17 on ubuntu
输出:
Before wait, lck.owns_lock() = 1
In main, lck.owns_lock() = 1
After wait, lck.owns_lock() = 1
但根据参考,我希望互斥锁在等待时解锁,即:
In main, lck.owns_lock() = 0
谁能告诉我为什么会这样?
【问题讨论】:
【参考方案1】:您必须进一步阅读:
解锁后,无论出于何种原因,都会重新获取锁定并等待退出。如果此函数因异常退出,也会重新获取锁。
因此始终保证在退出等待时重新获取锁。
【讨论】:
但是我问,为什么通过程序没有观察到相同的情况?输出与参考文档不一致。 main 中的 cout 在退出等待之前执行。 您的代码中实际上存在数据竞争。您正在从两个线程访问lck
,但std::unique_lock
不是为此而设计的。很容易检查mutex_
是否已解锁:尝试在sleep_for
之后立即获取main
中的互斥锁。以上是关于std::condition_variable 是不是真的在阻塞之前解锁了给定的 unique_lock 对象?的主要内容,如果未能解决你的问题,请参考以下文章
在等待通知 std::condition_variable 期间执行“等待回调”
std::atomic 和 std::condition_variable 等待、notify_* 方法之间的区别
在等待std :: condition_variable时如何处理系统时钟更改?
如何正确使用 std::condition_variable?