gpt4 book ai didi

c++ - 多个条件变量 : threads out of sync problem

转载 作者:行者123 更新时间:2023-12-03 07:00:40 25 4
gpt4 key购买 nike

我有一个线程正在做“工作”,它应该在条件变量通知它时报告进度。该线程正在等待条件变量。
其他线程正在等待 x 毫秒,然后通知条件变量继续。
我有 5 个条件变量(这是学校的练习),一旦每个都得到通知,就应该报告工作进度:
我遇到的问题是线程 2,即应该通知线程 1 的线程,经过所有 5 个检查点,最后只通知一次。所以我最终处于这样一种情况,即最终进度为 20%,线程 1 正在等待另一个通知,但线程 2 已完成所有通知。
我实现这个逻辑的缺陷在哪里?
代码如下:

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

using namespace std;

class Program {
public:
Program() {
m_progress = 0;
m_check = false;
}

bool isWorkReady() { return m_check; }

void loopWork() {
cout << "Working ... : " << endl;

work(m_cv1);
work(m_cv2);
work(m_cv3);
work(m_cv4);
work(m_cv5);

cout << "\nFinished!" << endl;
}

void work(condition_variable &cv) {
unique_lock<mutex> mlock(m_mutex);
cv.wait(mlock, bind(&Program::isWorkReady, this));
m_progress++;
cout << " ... " << m_progress * 20 << "%" << endl;
m_check = false;
}

void checkPoint(condition_variable &cv) {
lock_guard<mutex> guard(m_mutex);
cout << " < Checking >" << m_progress << endl;
this_thread::sleep_for(chrono::milliseconds(300));
m_check = true;
cv.notify_one();
}

void loopCheckPoints() {
checkPoint(m_cv1);
checkPoint(m_cv2);
checkPoint(m_cv3);
checkPoint(m_cv4);
checkPoint(m_cv5);
}

private:
mutex m_mutex;
condition_variable m_cv1, m_cv2, m_cv3, m_cv4, m_cv5;
int m_progress;
bool m_check;
};

int main() {
Program program;

thread t1(&Program::loopWork, &program);
thread t2(&Program::loopCheckPoints, &program);

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

return 0;
}

最佳答案

loopCheckPoints()线程持有锁一段时间,设置 m_check然后释放锁并立即继续再次捕获锁。 loopWork()线程可能没有在两者之间醒来以对 m_check 使用react改变。

  • 切勿长时间持有锁。尽可能快。如果不添加 sleep 就无法使程序运行s,你有问题。

  • 解决此问题的一种方法是检查工作人员是否实际设置了 m_check返回 false :
        void work(condition_variable& cv) {
    { // lock scope
    unique_lock<mutex> mlock(m_mutex);
    cv.wait(mlock, [this] { return m_check; });
    m_progress++;
    cout << " ... " << m_progress * 20 << "%" << endl;
    m_check = false;
    }
    // there's no need to hold the lock when notifying
    cv.notify_one(); // notify that we set it back to false
    }
        void checkPoint(condition_variable& cv) {
    // if you are going to sleep, do it without holding the lock
    // this_thread::sleep_for(chrono::milliseconds(300));

    { // lock scope
    lock_guard<mutex> guard(m_mutex);
    cout << "<Checking> " << m_progress << endl;
    m_check = true;
    }
    cv.notify_one(); // no need to hold the lock here
    {
    // Check that m_check is set back to false
    unique_lock<mutex> mlock(m_mutex);
    cv.wait(mlock, [this] { return not m_check; });
    }
    }

    关于c++ - 多个条件变量 : threads out of sync problem,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64058882/

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