https://en.cppreference.com/w/cpp/thread/lock_tag https://en.cppreference.com/w/cpp/thread/lock_tag
void transfer(bank_account &from, bank_account &to, int amount)
{
// lock both mutexes without deadlock
std::lock(from.m, to.m);
// make sure both already-locked mutexes are unlocked at the end of scope
std::lock_guard<std::mutex> lock1(from.m, std::adopt_lock);
std::lock_guard<std::mutex> lock2(to.m, std::adopt_lock);
// equivalent approach:
// std::unique_lock<std::mutex> lock1(from.m, std::defer_lock);
// std::unique_lock<std::mutex> lock2(to.m, std::defer_lock);
// std::lock(lock1, lock2);
from.balance -= amount;
to.balance += amount;
}
通过同时锁定两个互斥锁,他们能得到什么好处?
他们通过延迟锁在这里获得了什么?
请解释他们做出这一决定的原因。
如果我修改银行帐户而不锁定它,其他人可以尝试同时修改它。这是一场竞赛,结果将是不确定的行为(通常是丢失或神奇地创造金钱)。
转账时,我正在修改 2 个银行账户。所以他们都需要被锁定。
问题是,当锁定多个对象时,每个锁定器都必须以相同的顺序锁定和解锁,否则就会出现死锁。
当它是银行账户时,没有自然的锁顺序。数以千计的线程可以向各个方向转移资金。
因此,我们需要一种方法来锁定多个互斥锁,以解决这个问题 - 这就是std::lock
std::lock
仅锁定互斥体 - 它不保证从当前代码块退出时解锁。
std::lock_guard<>
在销毁时解锁它所引用的互斥锁(请参阅 RAII)。这使得代码在所有情况下都能正确运行 - 即使存在可能导致提前退出当前代码块而代码不流过语句的异常,例如to.m.unlock()
这里有一个很好的解释(带有示例):https://wiki.sei.cmu.edu/confluence/display/cplusplus/CON53-CPP.+避免+死锁+by+locking+in+a+predefined+order https://wiki.sei.cmu.edu/confluence/display/cplusplus/CON53-CPP.+Avoid+deadlock+by+locking+in+a+predefined+order
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)