使用 lock_guard 所采用的互斥体的锁是否会导致 UB?

Can using the lock of a mutex, adopted by a lock_guard, lead to a UB?

以下代码片段是否会由于使用 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()m1.lock() 之间抛出异常,那么 lock_guard 析构函数将再次解锁未锁定的互斥量,从而导致 UB。因此,即使保证不会抛出这些语句之间的所有内容,代码的 reader 也必须非常仔细地检查该代码以确保没有 UB。

unique_lockunique_lock上跳unlock/lock比直接在[=上跳unlock/lock会好得多15=] 以确保在特殊情况下正确解锁。