gpt4 book ai didi

C++ 条件等待竞争条件

转载 作者:行者123 更新时间:2023-11-28 04:07:40 24 4
gpt4 key购买 nike

假设我有一个程序,它有一个工作线程,它对队列中的数字求平方。问题是,如果工作很轻(需要很短的时间来完成),worker 就会完成工作并在它有时间甚至没有时间等待 worker 完成之前通知主线程。

我的简单程序如下所示:

#include <atomic>
#include <condition_variable>
#include <queue>
#include <thread>

std::atomic<bool> should_end;

std::condition_variable work_to_do;
std::mutex work_to_do_lock;

std::condition_variable fn_done;
std::mutex fn_done_lock;
std::mutex data_lock;

std::queue<int> work;
std::vector<int> result;

void worker() {
while(true) {
if(should_end) return;

data_lock.lock();
if(work.size() > 0) {
int front = work.front();
work.pop();
if (work.size() == 0){
fn_done.notify_one();
}
data_lock.unlock();
result.push_back(front * front);


} else {
data_lock.unlock();

// nothing to do, so we just wait
std::unique_lock<std::mutex> lck(work_to_do_lock);
work_to_do.wait(lck);
}
}
}


int main() {

should_end = false;
std::thread t(worker); // start worker

data_lock.lock();
const int N = 10;
for(int i = 0; i <= N; i++) {
work.push(i);
}
data_lock.unlock();

work_to_do.notify_one(); // notify the worker that there is work to do
//if the worker is quick, it signals done here already
std::unique_lock<std::mutex> lck(fn_done_lock);
fn_done.wait(lck);

for(auto elem : result) {
printf("result = %d \n", elem);
}

work_to_do.notify_one(); //notify the worker so we can shut it down
should_end = true;

t.join();
return 0;
}

最佳答案

您尝试在条件变量上使用通知本身作为工作完成的标志存在根本性缺陷。首先也是最重要的是 std::conditional_variable 可能有虚假唤醒,所以不应该这样做。您应该使用队列大小作为工作结束的实际条件,在所有线程中保护的相同互斥锁下检查和修改它,并对条件变量使用相同的互斥锁。然后你可以使用 std::conditional_variable 等到工作完成,但是你在检查队列大小之后才这样做,如果工作已经完成,你根本不会去等待。否则,您将在一个循环中检查队列大小(因为虚假唤醒)并等待它是否仍然不为空,或者您将 std::condition_variable::wait() 与内部具有循环的谓词一起使用.

关于C++ 条件等待竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58438152/

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