当在其他地方使用相同的互斥锁时,等待/通知unique_lock互斥锁是否安全lock_guard
Is it safe to wait/notify on unique_lock mutexes when same mutexes are used with lock_guard on somewhere else?
我使用以下等待/信号方式让线程相互通知。
std::condition_variable condBiz;
std::mutex mutexBar;
..
void Foo::wait()
{
std::unique_lock<std::mutex> waitPoint(mutexBar);
if (waitPoint.owns_lock())
{
condBiz.wait(waitPoint);
}
}
void Foo::signal()
{
std::unique_lock<std::mutex> waitPoint(mutexBar);
condBiz.notify_all();
}
void Foo::safeSection(std::function<void(void)> & f)
{
std::unique_lock<std::mutex> waitPoint(mutexBar);
f();
}
然后将锁定/解锁机制从 unique_lock 转换为lock_guard,因为我不会返回unique_lock在其他地方使用(等待/信号除外(,并且据说lock_guard开销较小:
void Foo::safeSection(std::function<void(void)> & f)
{
std::lock_guard<std::mutex> waitPoint(mutexBar); // same mutex object
f();
}
它有效。
这是否适用于所有平台,或者看起来仅适用于当前平台?unique_lock和lock_guard可以使用同一个互斥对象相互配合吗?
std::unique_lock
和 std::lock_guard
都将关联的互斥锁锁定在构造函数中,并在析构函数中将其解锁。
std::unique_lock
:
成员函数
(构造函数(构造一个unique_lock,可以选择锁定提供的互斥
(析构函数(解锁关联的互斥锁(如果拥有(
std::lock_guard
也是如此:
成员函数
(构造函数(构造一个lock_guard,可以选择锁定给定的互斥体
(析构函数(销毁lock_guard对象,解锁底层互斥锁
由于两者的行为相同,因此当用作 RAII 样式包装器时,我认为将它们一起使用没有任何障碍,即使使用相同的互斥锁也是如此。
在帖子的评论中已经指出,检查unique_lock是否在 Foo::wait(( 中拥有是没有意义的,因为此时关联的互斥锁必须由锁拥有才能使线程继续。
相反,您的条件变量应该检查一些有意义的条件,并且它应该在 while 循环中或使用 condition_variable::wait 的重载来执行此操作,该重载将谓词作为其第二个参数,这是C++标准所要求的,其效果为:
while (!pred()) wait(lock);
在 while 循环中检查谓词的原因是,除了条件可能已经满足因此无需等待这一事实之外,条件变量可能会虚假地唤醒,即使没有发出这样做的信号。
除此之外,信令线程没有理由不对关联的互斥锁使用lock_guard。 但我不清楚你想做什么。
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- 在其他文件中创建类时在 c++ 项目中不起作用
- 类与私有变量的其他类之间的线程安全性
- 将--whole archive链接器选项与CMake和具有其他库依赖项的库一起使用
- GlobalAlloc而不是其他分配方法
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 断言中的Fold表达式在某些计算机上编译,但在其他计算机上不编译
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 结构和双指针隐藏在其他结构中,多层混淆
- UE4在OnComponentBeginOverlap上铸造其他actor
- 当我在其中一个线程执行中(在activemq-cpp中)捕获到特定值时,我如何终止/停止所有其他线程
- MESI协议和std::atomic-它是否确保所有写入立即对其他线程可见?
- 保留对其他类的成员函数的引用
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 具有包含其他对象的类的对象创建顺序
- 让bool方法返回其他整数