c++ - 使用 lock_guard 采用的互斥锁可以导致 UB 吗?
问题描述
由于使用已被 a 采用的互斥锁的锁,以下代码段是否会导致未污染的行为 a lock_guard
?如果我在同一个片段中使用unique_lock
而不是它会安全吗?lock_guard
我知道有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();
}
解决方案
这个特定的代码可能是安全的,但我认为它不是很好的风格。问题是,如果在m1.unlock()
and之间抛出异常m1.lock()
,那么lock_guard
析构函数将再次解锁未锁定的互斥体,从而导致 UB。因此,即使保证这些语句之间的所有内容都不会抛出,代码的读者也必须非常仔细地检查该代码以确保没有 UB。
在特殊情况下使用unique_lock
并进行解锁/锁定舞蹈unique_lock
而不是直接在上会更好,mutex
以确保正确解锁。