c++在什么情境下使用固定顺序加锁无法解决死锁问题

c++并发编程实战是这么介绍的:

当有多个互斥量保护同一个类的独立实例时,一个操作对同一个类的两个不同实例进行数据的交换操作,为了保证数据交换操作的正确性,就要避免数据被并发修改,并确保每个实例上的互斥量都能锁住自己要保护的区域。不过,选择一个固定的顺序(例如,实例提供的第一互斥量作为第一个参数,提供的第二个互斥量为第二个参数),可能会适得其反:在参数交换了之后,两个线程试图在相同的两个实例间进行数据交换时,程序又死锁了!
阅读 3.1k
2 个回答

假设有一个类型A:
A a;
A b;

有一个函数:
void a_swap(A& a,A& b) {
a.mut_.lock();
b.mut_.lock();
...
}

thread 1:
a_swap(a, b);

thread 2:
a_swap(b, a);

实际上死锁的产生和程序具体逻辑相关,很难用一种通用的业务逻辑无关的方法完全避免。

新手上路,请多包涵

例如 Swap(a, b) 需要访问需要同时访问 a、b 的内部数据,理所当然对 a、b 都加锁再访问,按常规思路首先对第一个参数加锁,然后对第二个参数加锁。但当两个线程同时分别调用 Swap(a, b) 和 Swap(b, a) 时,就又出现了上述的“两个线程试图通过不同的顺序获取多个相同的锁”的情况,就有可能发生死锁。

参考:https://kakarotto9.github.io/...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题