C++ 如何理解C+中同一类的实例导致死锁问题+;行动中的并发?
我正在阅读,遇到了以下描述死锁的语句(第47~48页): 避免死锁的常见建议是始终以相同的顺序锁定两个互斥体:如果始终在互斥体B之前锁定互斥体A,则永远不会死锁。有时候这很简单,因为互斥体的用途不同,但有时候就不那么简单了,比如互斥体各自保护同一类的一个单独实例。例如,考虑在同一类的两个实例之间交换数据的操作;为了确保正确交换数据,而不受并发修改的影响,必须锁定两个实例上的互斥锁。但是,如果选择了固定的顺序(例如,作为第一个参数提供的实例的互斥体,然后作为第二个参数提供的实例的互斥体),这可能会适得其反:两个线程只需尝试在交换了参数的同两个实例之间交换数据,就会出现死锁 我对以下部分的含义感到非常困惑: 但是,如果选择了固定的顺序(例如,作为第一个参数提供的实例的互斥体,然后作为第二个参数提供的实例的互斥体),这可能会适得其反:两个线程只需尝试在交换了参数的同两个实例之间交换数据,就会出现死锁C++ 如何理解C+中同一类的实例导致死锁问题+;行动中的并发?,c++,multithreading,deadlock,C++,Multithreading,Deadlock,我正在阅读,遇到了以下描述死锁的语句(第47~48页): 避免死锁的常见建议是始终以相同的顺序锁定两个互斥体:如果始终在互斥体B之前锁定互斥体A,则永远不会死锁。有时候这很简单,因为互斥体的用途不同,但有时候就不那么简单了,比如互斥体各自保护同一类的一个单独实例。例如,考虑在同一类的两个实例之间交换数据的操作;为了确保正确交换数据,而不受并发修改的影响,必须锁定两个实例上的互斥锁。但是,如果选择了固定的顺序(例如,作为第一个参数提供的实例的互斥体,然后作为第二个参数提供的实例的互斥体),这可能会
在前面,它提到“
一个操作”
”,然后它提到“两个线程试图交换数据”
”。作者想要表达的实际场景是什么?交换操作是可交换的,因此您不能保证算法将使用相同的参数顺序执行此操作。因此,如果存在对象a
和b
,一个线程可以执行Swap(a,b)
,另一个Swap(b,a)
,最终结果锁以不同的顺序默认
如果时机不好,这将导致死锁
请注意,这可能更迫使三个对象和三个线程执行:
交换(a,b)
,交换(b,c)
,交换(c,a)
。在这里,锁定第一个参数而不是第二个参数也会导致死锁。交换操作是可交换的,因此不能保证算法将使用相同的参数顺序执行此操作。因此,如果存在对象a
和b
,一个线程可以执行Swap(a,b)
,另一个Swap(b,a)
,最终结果锁以不同的顺序默认
如果时机不好,这将导致死锁
请注意,这可能更迫使三个对象和三个线程执行:
交换(a,b)
,交换(b,c)
,交换(c,a)
。在这里,锁定第一个参数而不是第二个参数也会导致死锁。这指的是这样的情况:
你有一个功能
void foo(bar& a, bar& b) {
lock_guard<mutex> lock1(a.mutex);
...
lock_guard<mutex> lock2(b.mutex);
}
foo
可称为
foo(a, b);
在一个线程中,作为
foo(b, a);
另一方面。然后,就会出现死锁。这指的是这样一种情况: 你有一个功能
void foo(bar& a, bar& b) {
lock_guard<mutex> lock1(a.mutex);
...
lock_guard<mutex> lock2(b.mutex);
}
foo
可称为
foo(a, b);
在一个线程中,作为
foo(b, a);
另一方面。然后,你就陷入了僵局
在前面,它提到“一个操作”,然后提到“两个线程试图交换数据”
你错过了句子的结尾!它表示“两个线程试图在相同的两个实例之间交换数据”。它不是在线程之间交换数据,而是一个线程在类型的两个实例之间交换数据,另一个线程在相同的两个实例之间交换数据
在前面,它提到“一个操作”,然后提到“两个线程试图交换数据”
你错过了句子的结尾!它表示“两个线程试图在相同的两个实例之间交换数据”。它不是在线程之间交换数据,而是一个线程在类型的两个实例之间交换数据,另一个线程在相同的两个实例之间交换数据