Я пытаюсь понять использование условных переменных для реализации буферов производитель-потребитель.У меня есть следующий код, который реализует очередь для целых чисел (которые могут быть дескрипторами файлов Linux).Код работает, как и ожидалось, но я пытаюсь понять, почему.Операции enqueue и dequeue ожидают какую-то условную переменную, а затем сигнализируют другую условную переменную.Почему эти ожидания разблокировки?Это из-за ложных пробуждений?
#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();
}