gpt4 book ai didi

c++ - 生产者-消费者实现中的条件变量应该如何初始化

转载 作者:行者123 更新时间:2023-11-30 03:18:32 26 4
gpt4 key购买 nike

我正在尝试了解使用条件变量来实现生产者-消费者缓冲区。我有以下代码,它实现了一个整数队列(可以是 linux 文件描述符)。该代码按预期工作,但我试图理解原因。入队和出队操作都等待某个条件变量,然后再向另一个条件变量发出信号。为什么这些等待是畅通的?这是由于虚假唤醒造成的吗?

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

using namespace std::chrono_literals;
using std::cout;
using std::endl;

class FDQueue
{
std::mutex _mutex;
std::condition_variable _notEmptyCv, _notFullCv;
std::list<int> _fds;
size_t _maxSize;

public:
void add(int fd) {
std::unique_lock<std::mutex> locker(this->_mutex);
this->_notFullCv.wait(locker, [this](){return this->_fds.size() < this->_maxSize;});
cout<<"Enqueue "<<endl;
this->_fds.push_back(fd);
locker.unlock();
this->_notEmptyCv.notify_one();
}

int remove() {
std::unique_lock<std::mutex> locker(_mutex);
this->_notEmptyCv.wait(locker, [this](){return this->_fds.size() > 0;});
int fd = this->_fds.front();
this->_fds.pop_front();
cout<<"Dequeue"<<endl;
locker.unlock();
this->_notFullCv.notify_all();
return fd;
}

FDQueue(size_t maxSize) : _maxSize(maxSize) {}
};

FDQueue queue(5);

void producer() {
while (true) {
queue.add(0);
std::this_thread::sleep_for(2s);
}
}
void consumer() {
while (true) {
queue.remove();
}
}

int main() {
std::thread t1(producer);
std::thread t2(consumer);
t1.join();
t2.join();
}

最佳答案

add waits on _notFullCv, and remove waits on _notEmptyCv. How do these conditional variables get signaled for the very first time?

他们没有。如果您查看 documentation ,接受锁 l 和谓词 predstd::condition_variable::wait 的重载被有效地实现为...

while (!pred())
wait(l);

在您的案例中,重要的部分是在等待之前检查条件。因此,第一次调用 add 会发现队列未满,并且不会调用 std::condition_variable::wait(没有谓词)。

关于c++ - 生产者-消费者实现中的条件变量应该如何初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54672365/

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