为什么在同一条件变量上使用多个互斥锁会使此代码崩溃?

Why does using multiple mutex's on the same condition variable crash this code?

本文关键字:崩溃 代码 一条 条件 变量 为什么      更新时间:2023-10-16

在下面的代码中,我试图使其最小限度地可验证,运行良好,并做了它应该做的事情(无论我在线程中传递哪个顺序,都按顺序打印1,2,3(。然而,如果我在函数第三行中将m1更改为m2,则此代码将崩溃,并显示消息"terminated without a active exception"。为什么我不能使用相同的条件变量同时锁定两个不同的互斥对象?

#include <functional>
#include <mutex>
#include <condition_variable>
#include <future>
#include <iostream>
void printFirst() {
cout << "1";
}
void printSecond() {
cout << "2";
}
void printThird() {
cout << "3";
}
struct test {
condition_variable c, c2;
int count = 0;
mutex m1,m2;
void first(function<void()> printFirst) {
printFirst();
count++;
c.notify_all();
}
void second(function<void()> printSecond) {
unique_lock<mutex> sL1(m1);
c.wait(sL1,[&]{return count>=1;});
printSecond();
count+=1;
c.notify_all();
}
void third(function<void()> printThird) {
unique_lock<mutex> sL2(m1); //If I make m1, m2, this code crashes
c.wait(sL2,[&]{return count>=2;});
printThird();
}
};
int main() {
test t;
function<void()> printFirstN =[&](){ t.first(printFirst);};
function<void()> printSecondN=[&](){ t.second(printSecond);};
function<void()> printThirdN=[&](){ t.third(printThird);};
std::thread t1(printFirstN);
std::thread t2( printThirdN);
std::thread t3( printSecondN);
t1.join();
t2.join();
t3.join();
}

你不能这样做,因为C++标准说你不能。

33.5.3类condition_variable[thread.cocondvar]

无效等待(unique_lock&lock(;

要求:lock.owns_lock((为true,lock.mutex((由调用线程,以及

(9.1(--没有其他线程正在等待condition_variable对象或

(9.2(--lock.mmutex((返回相同的所有并发提供的每个锁参数的值正在等待(通过wait、wait_fo或wait_until(线程。

第二个子句要求,如果所有执行线程也在条件变量上进行阻塞,那么它们必须锁定相同的互斥对象。

(以上是针对不需要额外参数的wait方法,对所有重载/变体都重复相同的要求,包括代码使用的带有谓词的重载/变体(。