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;
}
Run Code Online (Sandbox Code Playgroud)
通过一次锁定两个互斥锁可以获得什么?
他们在这里得到了什么?
请解释他们的决定背后的原因.
如果我修改银行帐户而不锁定它,其他人可能会尝试同时修改它.这是一场比赛,结果将是未定义的行为(通常是丢失或神奇创造的钱).
在转账时,我正在修改2个银行账户.所以他们都需要被锁定.
问题是当锁定多个东西时,每个锁定器必须以相同的顺序锁定和解锁,否则我们会遇到死锁.
当它是银行账户时,没有自然的锁定顺序.成千上万的线程可以向各个方向转移资金.
所以我们需要一种方法来锁定多个互斥锁,以此方式解决这个问题 std::lock
std::lock 仅锁定互斥锁 - 它不保证在退出当前代码块时解锁.
std::lock_guard<>解锁它在破坏时所指的互斥锁(参见RAII).这使得代码在所有情况下都能正常运行 - 即使存在可能导致提前退出当前代码块的异常,而不会使代码流过语句,例如to.m.unlock()
这里有一个很好的解释(带例子):https://wiki.sei.cmu.edu/confluence/display/cplusplus/CON53-CPP.+Avoid+deadlock+by+locking+in+a+predefined+order
| 归档时间: |
|
| 查看次数: |
311 次 |
| 最近记录: |