Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何理解C+中同一类的实例导致死锁问题+;行动中的并发?_C++_Multithreading_Deadlock - Fatal编程技术网

C++ 如何理解C+中同一类的实例导致死锁问题+;行动中的并发?

C++ 如何理解C+中同一类的实例导致死锁问题+;行动中的并发?,c++,multithreading,deadlock,C++,Multithreading,Deadlock,我正在阅读,遇到了以下描述死锁的语句(第47~48页): 避免死锁的常见建议是始终以相同的顺序锁定两个互斥体:如果始终在互斥体B之前锁定互斥体A,则永远不会死锁。有时候这很简单,因为互斥体的用途不同,但有时候就不那么简单了,比如互斥体各自保护同一类的一个单独实例。例如,考虑在同一类的两个实例之间交换数据的操作;为了确保正确交换数据,而不受并发修改的影响,必须锁定两个实例上的互斥锁。但是,如果选择了固定的顺序(例如,作为第一个参数提供的实例的互斥体,然后作为第二个参数提供的实例的互斥体),这可能会

我正在阅读,遇到了以下描述死锁的语句(第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);
另一方面。然后,你就陷入了僵局

在前面,它提到“一个操作”,然后提到“两个线程试图交换数据”

你错过了句子的结尾!它表示“两个线程试图在相同的两个实例之间交换数据”。它不是在线程之间交换数据,而是一个线程在类型的两个实例之间交换数据,另一个线程在相同的两个实例之间交换数据

在前面,它提到“一个操作”,然后提到“两个线程试图交换数据”

你错过了句子的结尾!它表示“两个线程试图在相同的两个实例之间交换数据”。它不是在线程之间交换数据,而是一个线程在类型的两个实例之间交换数据,另一个线程在相同的两个实例之间交换数据