生产者消费者实现中的条件变量应如何初始化
How should conditional variables in producer-consumer implementations be initialized
我正在尝试了解条件变量实现生产者消费者缓冲区。我有以下代码,该代码实现了整数的队列(可能是Linux文件描述符)。该代码按预期工作,但我试图理解原因。在向其他条件变量发出信号之前,对方和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();
}
在_notfullcv上添加等待,然后在_notemptycv上删除等待。这些如何 有条件的变量第一次发出信号?
他们没有。如果您查看文档,那么接受锁定l
和谓词pred
的std::condition_variable::wait
的过载实际上是...
while (!pred())
wait(l);
在您的情况下,重要的部分是在等待之前检查了条件。因此,第一个呼叫add
会发现队列不满,并且不会拨打std::condition_variable::wait
(没有谓词)。
相关文章:
- 初始值设定项列表是否只接受使用相同类型的值初始化变量?
- 在 C++ 中访问 lambda 捕获初始化变量
- 为什么C++不支持对未初始化变量进行智能分析?
- 使用 clang++ 和 g++ 在C++中初始化变量
- C++使用 lambda 初始化变量
- 如何在初始化列表中的构造函数之后初始化变量/对象?
- C++ - 输出与初始化变量不同?
- C++/Win32 构造函数不使用从对话框获取的字符串初始化变量
- 在C++中,为什么int可以使用new运算符初始化变量,而double不能
- 具有静态存储持续时间的常量初始化变量的初始化顺序
- C++ 中的初始化变量
- C++中未初始化变量的值
- 如何在需要提及需要循环声明的其他类的类中初始化变量?
- 我想知道在构造函数中初始化变量时的生命周期
- 读取恰好具有良好值的未初始化变量
- 如何在 getter 的父类中初始化变量的情况下访问子类中的变量
- 为什么在 c++ 中有多种初始化变量的方法
- 没有参数的默认构造函数是否总是初始化变量?
- 是否可以使用 lambda 初始化变量(删除复制 ctor 时)
- 使用构造函数跳闸UB的新放置后使用初始化变量