gpt4 book ai didi

C++11 简单生产者消费者多线程

转载 作者:行者123 更新时间:2023-12-03 08:15:52 25 4
gpt4 key购买 nike

我正在尝试自学多线程,我在这里遵循了本教程:https://www.classes.cs.uchicago.edu/archive/2013/spring/12300-1/labs/lab6/

如果你一直滚动到底部,就会有一个生产者-消费者的示例片段,它要求我们解决此代码中发现的竞争条件:

#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <chrono>
#include <queue>
using namespace std;

int main() {
int c = 0;
bool done = false;
queue<int> goods;

thread producer([&]() {
for (int i = 0; i < 500; ++i) {
goods.push(i);
c++;
}

done = true;
});

thread consumer([&]() {
while (!done) {
while (!goods.empty()) {
goods.pop();
c--;
}
}
});

producer.join();
consumer.join();
cout << "Net: " << c << endl;
}

最后的净值应该是0,这是我的尝试:

#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <chrono>
#include <queue>
#include <atomic>
using namespace std;


int main() {

int c = 0;

bool done = false;
queue<int> goods;
mutex mtx;
condition_variable cond_var;

// thread to produce 500 elements
thread producer([&]() {

for (int i = 0; i < 500; ++i) {
// lock critical secion
unique_lock<mutex> lock(mtx);

goods.push(i);
c++;
lock.unlock();

// notify consumer that data has been produced
cond_var.notify_one();
}

// notify the consumer that it is done
done = true;
cond_var.notify_one();


});

// thread to consume all elements
thread consumer([&]() {

while (!done) {
unique_lock<mutex> lock(mtx);
while (!goods.empty()) {
goods.pop();
c--;
}
// unlocks lock and wait until something in producer gets put
cond_var.wait(lock);
}
});

producer.join();
consumer.join();
cout << "Net: " << c << endl;
}

我觉得我从根本上错过了一些东西。我相信我遇到的最大问题是消费者使用 cond_var.wait() ,因为如果生产者将“done”设置为 true 那么消费者将不会返回到 while(!goods.empty()) 。但我不知道如何解决它。

任何提示、解释甚至不同的方法将不胜感激!

最佳答案

制作人:

thread producer([&]() {

for (int i = 0; i < 500; ++i)
{
{
// Just have a lock while interacting with shared items.
unique_lock<mutex> lock(mtx);
goods.push(i);
c++;
}
cond_var.notify_one();
}

// Lock to update shared state.
unique_lock<mutex> lock(mtx);
done = true;
cond_var.notify_one();
});

消费者

thread consumer([&]() {

// This loop exits when
// done => true
// AND goods.empty() => true

// Acquire lock before checking shared state.
unique_lock<mutex> lock(mtx);

while (!(done && goods.empty()))
{
// Wait until there is something in the queue to processes
// releasing lock while we wait.
// Break out if we are done or goods is not empty.
cond_var.wait(lock, [&](){return done || !goods.empty();});

// You now have the lock again, so modify shared state is allowed
// But there is a possibility of no goods being available.
// So let's check before doing work.
if (!goods.empty())
{
goods.pop();
c--;
}
}
});

或者,如果我们只是简单地解决竞争条件。我们可以简单地检查 done 的状态并确保没有其他变量发生交互。

制作人:

thread producer([&]() {

// The consumer is not allowed to touch goods
// until you are finished. So just use with
// no locks.
for (int i = 0; i < 500; ++i)
{
goods.push(i);
c++;
}

// Lock to update shared state.
// Tell consumer we are ready for processing.
unique_lock<mutex> lock(mtx);
done = true;
cond_var.notify_one();
});

消费者

thread consumer([&]() {

// Acquire lock before checking shared state.
unique_lock<mutex> lock(mtx);
cond_var.wait(lock, [&](){return done;});

// We now know the consumer has finished all updates.
// So we can simply loop over the goods and processes them
while (!goods.empty())
{
goods.pop();
c--;
}
});

关于C++11 简单生产者消费者多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69453363/

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