提问人:SameemSh. 提问时间:6/25/2023 更新时间:6/26/2023 访问量:81
为什么使用具有唯一锁的延迟锁
Why use defer lock with unique lock
问:
为什么要使用延迟锁定? 先获得所有权后锁定是什么? 获得所有权和锁定有点不一样。 如果我们使用互斥锁的唯一锁而不是锁定来获得所有权,它是否仍然容易出现竞争条件?
void fun1(std::mutex &m){
std::lock_guard<std::mutex> mlock(m);
//multiple lines
}
void fun2(std::mutex &m){
std::unique_lock<std::mutex,std::defer_lock> mlock(m);
//multiple lines
mlock.lock();
//multiple lines
}
答:
1赞
Solomon Slow
6/25/2023
#1
如果我们拥有所有权怎么办......?
这不会“获得”互斥锁的所有权:m
std::unique_lock<std::mutex,std::defer_lock> mlock(m);
实际上,它说,我现在想构造这个 RAII 对象,但我不会锁定(即“获得所有权”),直到以后。mlock
m
m
它还会容易受到竞争条件的影响吗?
绝对。是的。
{
std::unique_lock<std::mutex,std::defer_lock> mlock(m);
// Here, we still are prone to race conditions because m is not locked.
...
std::lock(m);
// Now, it's safe to use whatever data m protects.
...
}
// And here, m is guaranteed to be unlocked again.
...
对评论的回应,如下
使用延迟锁定的任何用例?
我能想到的唯一用例*类似于@Mat向您推荐的 cppreference 网页上显示的内容。
- 您想要锁定两个或多个互斥锁,并且
- 您希望控制互斥锁的锁定顺序,以便避免死锁,并且
- 您希望使用 RAII 来确保线程在不解锁所有互斥锁的情况下无法离开块。
所以,你写这样的东西:
{
// Create RAII objects. `defer_lock` means, "Just create the objects,
// but don't actually lock the mutexes. I solemnly swear that
// that _I_ will lock them before this story ends."
std::unique_lock<std::mutex, std::defer_lock> ulk_A(mutex_A);
std::unique_lock<std::mutex, std::defer_lock> ulk_B(mutex_B);
// lock both mutexes
if (...Deadlock avoidance requires A to be locked first...) {
std::lock(mutex_A);
std::lock(mutex_B);
}
else {
std::lock(mutex_B);
std::lock(mutex_A);
}
// _Now_ it's safe to access any shared data that are protected by
// mutex_A or mutex_B.
...
}
// Can't leave the block without both mutexes being unlocked again.
* 也许还有其他用途。仅仅因为*我*无法想象某件事并不意味着它不在那里等待别人想象它。
评论
0赞
SameemSh.
6/25/2023
使用延迟锁定的任何用例?
0赞
Solomon Slow
6/26/2023
@SameemSh,请参阅我更新的答案。
评论