gpt4 book ai didi

c++ - 为什么在同一个条件变量上使用多个互斥量会使这段代码崩溃?

转载 作者:行者123 更新时间:2023-11-30 01:01:38 24 4
gpt4 key购买 nike

在下面的代码中,我已尝试使其具有最低限度的可验证性,它运行良好并执行应有的操作(无论我在线程中传递的顺序如何,都按顺序打印 1、2、3)。但是,如果我在第三个函数中注释的行中将 m1 更改为 m2,则此代码会崩溃并显示消息“在没有事件异常的情况下终止”。为什么我不能使用相同的条件变量同时锁定两个不同的互斥体?

#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 Class condition_variable [thread.condition.condvar]

void wait(unique_lock& lock);

Requires: lock.owns_lock() is true and lock.mutex() is locked by the calling thread, and either

(9.1) — no other thread is waiting on this condition_variable object or

(9.2) — lock.mutex() returns the same value for each of the lock arguments supplied by all concurrently waiting (via wait, wait_for, or wait_until) threads.

第二个子句强加了一个要求,即所有执行线程必须锁定相同的互斥体,如果它们也在条件变量上阻塞的话。

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

关于c++ - 为什么在同一个条件变量上使用多个互斥量会使这段代码崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58739807/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com