gpt4 book ai didi

c++ - 竞争条件 2 个线程交替

转载 作者:行者123 更新时间:2023-11-30 04:48:58 26 4
gpt4 key购买 nike

所以我希望程序输出 1\n2\n1\n2\n1\n2\n 但它似乎卡在了某个地方。但是,当我调试它并在声明 t2 后立即在 cv1.notify_one() 处设置断点时,它会执行 ??

#include <iostream>
#include <mutex>
#include <thread>
#include <condition_variable>

using namespace std;

mutex cout_lock;

condition_variable cv1, cv2;
mutex mtx1;
unique_lock<std::mutex> lck1(mtx1);
mutex mtx2;
unique_lock<std::mutex> lck2(mtx2);

const int COUNT = 3;

int main(int argc, char** argv)
{

thread t1([&](){
for(int i = 0; i < COUNT; ++i)
{
cv1.wait(lck1);
cout << "1" << endl;
cv2.notify_one();
}
});

thread t2([&](){
for(int i = 0; i < COUNT; ++i)
{
cv2.wait(lck2);
cout << "2" << endl;
cv1.notify_one();
}
});

cv1.notify_one();

t1.join();
t2.join();

return 0;
}

最佳答案

有几个缺陷:

  1. 您想保护您的输出。因此,您只需要一个互斥锁,这样一次只有一个线程可以完成它们的工作。
  2. 您可能会错过对您的条件变量的通知。
  3. 您的全局 unique_lock 在其构造函数中获取互斥锁。所以你一直持有锁,没有线程可以取得进展。 你的全局 unique_lock 在它们的构造函数中获取互斥锁的锁。这是在主线程中完成的。 T1 和 T2 正在通过 condition_variable 解锁它们。这是未定义的行为(拥有互斥量的线程必须解锁它)。

这是正确使用条件变量方法的秘诀:

  1. 有一个你感兴趣的条件。在这种情况下,某种变量可以记住轮到谁了。
  2. 通过一个(ONE!)mutex
  3. 保护这个变量
  4. 将(一个!)condition_variable 与第 2 点的互斥量和第 1 点的条件结合使用。

这确保:

  • 在任何时候都只有一个线程可以查看和/或更改您的状况。
  • 如果线程到达代码中可能等待条件变量的位置,它首先检查条件。也许线程甚至不需要休眠,因为他想要等待的条件已经为真。为此,线程必须获取互斥锁,检查条件并决定做什么。在这样做的同时,他拥有锁。条件不能改变,因为线程本身有锁。所以你不能错过通知。

这导致以下代码 ( see live here ):

#include <iostream>
#include <mutex>
#include <thread>
#include <condition_variable>

using namespace std;

int main(int argc, char** argv)
{
condition_variable cv;
mutex mtx;
bool runt1 = true;
bool runt2 = false;
constexpr int COUNT = 3;

thread t1([&]()
{
for(int i = 0; i < COUNT; ++i)
{
unique_lock<std::mutex> lck(mtx);
cv.wait(lck, [&](){ return runt1; });
cout << "1" << endl;
runt1 = false;
runt2 = true;
lck.unlock();
cv.notify_one();
}
});

thread t2([&]()
{
for(int i = 0; i < COUNT; ++i)
{
unique_lock<std::mutex> lck(mtx);
cv.wait(lck, [&](){ return runt2; });
cout << "2" << endl;
runt1 = true;
runt2 = false;
lck.unlock();
cv.notify_one();
}
});

t1.join();
t2.join();

return 0;
}

关于c++ - 竞争条件 2 个线程交替,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55602244/

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