简体   繁体   English

使用 lock_guard 采用的互斥锁可以导致 UB 吗?

[英]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_lockunique_lock上进行解锁/锁定舞蹈,而不是直接在mutex锁上,以确保在特殊情况下正确解锁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM