gpt4 book ai didi

c++ - 条件变量基本示例

转载 作者:行者123 更新时间:2023-12-01 22:40:04 35 4
gpt4 key购买 nike

我正在学习 C++11 中的条件变量,并根据示例代码编写了此程序。

目标是将生产者生成并由消费者插入 vector 的前十个自然整数累积在 vector 中。然而它不起作用,因为例如在某些运行中, vector 仅包含 1、7 和 10。

#include <mutex>
#include <condition_variable>
#include<vector>
#include <iostream>
#include <cstdio>

std::mutex mut;
#define MAX 10
int counter;
bool isIncremented = false;
std::vector<int> vec;
std::condition_variable condvar;

void producer() {
while (counter < MAX) {
std::lock_guard<std::mutex> lg(mut);
++counter;
isIncremented = true;
condvar.notify_one();
}
}

void consumer() {
while (true) {
std::unique_lock<std::mutex> ul(mut);
condvar.wait(ul, [] { return isIncremented; });
vec.push_back(counter);
isIncremented = false;
if (counter >= MAX) {
break;
}
}
}

int main(int argc, char *argv[]) {
std::thread t1(consumer);
std::thread t2(producer);
t2.join();
t1.join();

for (auto i : vec) {
std::cout << i << ", ";
}
std::cout << std::endl;
// Expected output: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
// Example of actual output: 1, 7, 10,

std::cout << "Press enter to quit";
getchar();
return 0;
}

最佳答案

问题是你只记得制作人最后制作的数字。而且你的生产者永远不会等到消费者消费完它生产的东西。如果您的生产者线程在消费者线程开始运行之前执行其循环的多次迭代(这并非不可能,因为循环没有做太多事情),那么消费者将只能看到生产者生成的最后一个数字,并且只能推送那个进入 vector ......

要解决这个问题,要么使用第二个条件变量让生产者等待某人获取它生成的最后一个结果,要么使用可以在生产者和消费者之间存储多个结果的东西,或者两者的组合......

注意:通知条件变量不是阻塞调用。如果是的话,它必须要求您交出互斥体,以便它可以在内部释放它,否则您将陷入僵局。 notify_one()只会唤醒正在等待条件变量的线程之一并返回。唤醒线程阻塞的等待调用将在返回之前重新获取互斥锁。在您的情况下,消费者线程不太可能被唤醒,然后无法重新获取互斥锁并立即再次阻塞,因为您的生产者线程在调用 notify_one() 时仍然保留着互斥锁。因此,作为一般经验法则,如果您在调用通知之前持有与条件变量关联的互斥锁,则需要释放该互斥锁...

关于c++ - 条件变量基本示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59154178/

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