[英]Can using the lock of a mutex, adopted by a lock_guard, lead to a UB?
Can the following snippet cause an undefiled behaviora due to using the lock of the mutex already adopted by a lock_guard
?由于使用
lock_guard
已经采用的互斥锁的锁,以下代码段会导致未污染的行为吗? and will it be safe if I use unique_lock
instead of lock_guard
in the same snippet?如果我在同一个片段中使用
unique_lock
而不是lock_guard
会安全吗? I know that there are std::unique_lock<T>::lock/unlock()
我知道有
std::unique_lock<T>::lock/unlock()
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
std::mutex m1;
void func(int count ){
std::lock_guard lG{m1};
std::cout << std::this_thread::get_id() << std::endl;
if(count == 1) {
m1.unlock();
std::this_thread::sleep_for(std::chrono::duration<size_t, std::ratio<1, 1>>{6});
m1.lock();
}
std::cout << std::this_thread::get_id() << std::endl;
}
int main()
{
std::thread t1 {func, 1};
std::thread t2 {func, 9};
t1.join();
t2.join();
}
This particular code is likely safe, but I would not consider it good style.这个特定的代码可能是安全的,但我认为它不是很好的风格。 The problem is that if something throws an exception between
m1.unlock()
and m1.lock()
, then the lock_guard
destructor is going to unlock the unlocked mutex a second time, causing UB.问题是,如果在
m1.unlock()
和m1.lock()
之间抛出异常,那么lock_guard
析构函数将再次解锁未锁定的互斥锁,从而导致 UB。 So even if everything between these statements is guaranteed not to throw, the reader of the code has to inspect that code all too closely to ensure there is no UB.因此,即使保证这些语句之间的所有内容都不会抛出,代码的读者也必须非常仔细地检查该代码以确保没有 UB。
It would be much better to use unique_lock
and do the unlock/lock dance on the unique_lock
instead of directly on the mutex
to ensure proper unlocking in the exceptional case.最好使用
unique_lock
并在unique_lock
上进行解锁/锁定舞蹈,而不是直接在mutex
锁上,以确保在特殊情况下正确解锁。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.