I'm trying to implement a blocking queue with limited size, for one provider and multiple consumers. it is working well when the consumer is sleep()ing for 1 second, but hangs when there is no sleep. what am I doing wrong?
here is my code:
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>
using namespace std;
template <class T> class BlockingQueue: public queue<T> {
public:
BlockingQueue() {
queue<T>();
}
BlockingQueue(int size) {
maxSize = size;
queue<T>();
}
void push(T item) {
unique_lock<std::mutex> wlck(writerMutex);
while(Full())
isFull.wait(wlck);
queue<T>::push(item);
if(notEmpty())
isEmpty.notify_one();
}
bool notEmpty() {
return !queue<T>::empty();
}
bool Full(){
return queue<T>::size() >= maxSize;
}
T pop() {
unique_lock<std::mutex> lck(readerMutex);
popMutex.lock();
while(queue<T>::empty()) {
isEmpty.wait(lck);
}
T value = queue<T>::front();
queue<T>::pop();
if(!Full())
isFull.notify_all();
popMutex.unlock();
return value;
}
private:
int maxSize;
std::mutex readerMutex;
std::mutex popMutex;
std::mutex writerMutex;
condition_variable isFull;
condition_variable isEmpty;
};
void runProvider(BlockingQueue<int>* Q) {
int number=0;
while(1) {
Q->push(number);
cout<<"provide "<<number<<endl;
number++;
}
}
void runConsumer(int n,BlockingQueue<int>* Q) {
int number;
while(1) {
number = Q->pop();
cout<<"consume#"<<n<<": "<<number<<endl;
}
}
int main(int argc, char** argv) {
BlockingQueue<int> *Queue = new BlockingQueue<int>(10);
cout<<"starting provider"<<endl;
std:thread provider(runProvider, Queue);
sleep(1);
cout<<"starting consumer"<<endl;
std::thread consumer1(runConsumer, 1,Queue);
std::thread consumer2(runConsumer, 2,Queue);
provider.join();
delete(Queue);
return 0;
}
Here is my fixed code for blocking queue with multiple providers and multiple consumers and limited queue size:
template <class T> class BlockingQueue: public queue<T> {
public:
BlockingQueue(int size) {
maxSize = size;
}
void push(T item) {
unique_lock<std::mutex> wlck(writerMutex);
while(Full())
isFull.wait(wlck);
queue<T>::push(item);
isEmpty.notify_all();
}
bool notEmpty() {
return !queue<T>::empty();
}
bool Full(){
return queue<T>::size() >= maxSize;
}
T pop() {
unique_lock<std::mutex> lck(readerMutex);
while(queue<T>::empty()) {
isEmpty.wait(lck);
}
T value = queue<T>::front();
queue<T>::pop();
if(!Full())
isFull.notify_all();
return value;
}
private:
int maxSize;
std::mutex readerMutex;
std::mutex writerMutex;
condition_variable isFull;
condition_variable isEmpty;
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.