简体   繁体   English

不锁定互斥锁的 std::lock_guard 和 std::adopt_lock 行为

[英]std::lock_guard and std::adopt_lock behaviour without locking the mutex

I have been learning about the usage of std::lock and std::lock_guard and most examples follow the pattern below:我一直在学习std::lockstd::lock_guard的用法,大多数示例都遵循以下模式:

std::lock(m1, m2);
std::lock_guard<std::mutex> guard1(m1, std::adopt_lock);
std::lock_guard<std::mutex> guard2(m2, std::adopt_lock);
//Do something here

Then I came across an example that utilized the same pattern you would use if you were using std::unique_lock , but with lock_guard :然后我遇到了一个示例,该示例使用了与使用std::unique_lock使用的相同模式,但使用了lock_guard

std::lock_guard<std::mutex> guard1(m1, std::adopt_lock);
std::lock_guard<std::mutex> guard2(m2, std::adopt_lock);
std::lock(m1, m2);
//Do something here

My question is, would this cause undefined behaviour if you use the second pattern and an exception occurs before you reach std::lock ?我的问题是,如果您使用第二种模式并且在到达std::lock之前发生异常,这会导致未定义的行为吗?

PS I am aware that C++17 introduced std::scoped_lock and that std::lock_guard is still around mainly for compatibility with older code. PS 我知道 C++17 引入了std::scoped_lock并且std::lock_guard仍然存在,主要是为了与旧代码兼容。

Your second example is undefined behavior;你的第二个例子是未定义的行为; adopt_lock constructor presumes that the mutex is already held. adopt_lock构造函数假定互斥锁已经被持有。 This UB is triggered at construction, not at destruction or when an exception is thrown.这个 UB 在构造时触发,而不是在销毁或抛出异常时触发。


If you used unique_lock instead of scoped_lock , it has a:如果您使用unique_lock而不是scoped_lock ,则它具有:

unique_lock( mutex_type& m, std::defer_lock_t t ) noexcept;

constructor, which permits your std::lock use with a slight change:构造函数,它允许您使用std::lock稍作更改:

std::unique_lock<std::mutex> guard1(m1, std::defer_lock);
std::unique_lock<std::mutex> guard2(m2, std::defer_lock);
std::lock(guard1, guard2);

Now, unique_lock does track if it has the lock, so there is possible memory and performance overhead;现在, unique_lock会跟踪它是否有锁,因此可能存在内存和性能开销; if unique_lock s are local to the scope, compilers can and will optimize out that if it can prove it safe.如果unique_lock是作用域本地的,编译器可以并且会优化它,如果它可以证明它是安全的。

And if the compiler can't prove it safe, quite often it isn't safe.如果编译器不能证明它是安全的,那么它通常是不安全的。

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

相关问题 使用 std::adopt_lock 选项构造后,std::lock_guard 是否释放互斥锁? - Does std::lock_guard release the mutex after constructed with std::adopt_lock option? 为什么 std::lock_guard 在使用 std::adopt_lock 后会释放锁? - Why does std::lock_guard release the lock after using std::adopt_lock? 使用 std::lock_guard 数组锁定 std::mutex 数组 - Locking an array of std::mutex using a std::lock_guard array std :: lock_guard()用于锁定的std :: mutex - std::lock_guard() for a locked std::mutex 是否有 std::lock_guard 的简写<std::mutex>锁(米)? - Is there a shorthand for std::lock_guard<std::mutex> lock(m)? 有什么更好的std :: lock_guard <std::mutex> 锁(std :: mutex Mutex_var); 或std :: mutex Mutex_var.lock(); - Whats better std::lock_guard<std::mutex> lock(std::mutex mutex_var); or std::mutex mutex_var.lock(); std::lock_guard<std::mutex> 施工中的段错误? - std::lock_guard<std::mutex> segfaults on construction? 冲突声明 std::lock_guard<std::mutex></std::mutex> - conflicting declaration std::lock_guard<std::mutex> std::unique_lock<std::mutex> 或 std::lock_guard<std::mutex> ? - std::unique_lock<std::mutex> or std::lock_guard<std::mutex>? 首先锁定和创建 lock_guard(adopt_lock) 与创建 unique_lock(defer_lock) 和锁定有什么区别? - What's the difference between first locking and creating a lock_guard(adopt_lock) and creating a unique_lock(defer_lock) and locking?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM