Windows下一個帶有大小限制的併發阻塞隊列,實現的比較簡單。
#ifndef BLOCKINGQUEUE_H_
#define BLOCKINGQUEUE_H_
#include <queue>
#include <windows.h>
using namespace std;
template <typename T>
class BoundedBlockingQueue
{
public:
BoundedBlockingQueue(int size) : maxSize(size)
{
_lock = CreateMutex(NULL,false,NULL);
_rsem = CreateSemaphore(NULL,0,size,NULL);
_wsem = CreateSemaphore(NULL,size,size,NULL);
}
~BoundedBlockingQueue()
{
CloseHandle(_lock);
CloseHandle(_rsem);
CloseHandle(_wsem);
}
void push(const T& data);
T pop();
bool empty()
{
WaitForSingleObject(_lock,INFINITE);
bool is_empty = _array.empty();
ReleaseMutex(_lock);
return is_empty;
}
private:
deque<T> _array;
int maxSize;
HANDLE _lock;
HANDLE _rsem, _wsem;
};
template <typename T>
void BoundedBlockingQueue <T>::push(const T& value )
{
WaitForSingleObject(_wsem,INFINITE);
WaitForSingleObject(_lock,INFINITE);
_array.push_back(value);
ReleaseMutex(_lock);
ReleaseSemaphore(_rsem,1,NULL);
}
template <typename T>
T BoundedBlockingQueue<T>::pop()
{
WaitForSingleObject(_rsem,INFINITE);
WaitForSingleObject(_lock,INFINITE);
T _temp = _array.front();
_array.pop_front();
ReleaseMutex(_lock);
ReleaseSemaphore(_wsem,1,NULL);
return _temp;
}
#endif
主函數調用測試:一個生產者、兩個消費者使用這個隊列進行測試。
#include "BlockingQueue.h"
#include <windows.h>
#include <iostream>
using namespace std;
bool is_over = false;
DWORD WINAPI produce(LPVOID lppara)
{
BoundedBlockingQueue<int> *queue = (BoundedBlockingQueue<int> *)lppara;
while(1)
{
for(int i=1; i<=50; ++i)
{
queue->push(i);
cout<<GetCurrentThreadId()<<" put a data: "<<i<<endl;
Sleep(10); //producer is fast
}
is_over = true;
break;
}
return NULL;
}
DWORD WINAPI consume(LPVOID lppara)
{
BoundedBlockingQueue<int> *queue = (BoundedBlockingQueue<int> *)lppara;
while(1)
{
int d = queue->pop();
cout<<GetCurrentThreadId()<<" get data: "<<d<<endl;
//double check
if(is_over && queue->empty())
{
cout<<"OVER!"<<endl;
break;
}
Sleep(10); //consumer is slow
}
return NULL;
}
int main()
{
DWORD write_data;
DWORD read_data;
DWORD read_data1;
BoundedBlockingQueue<int> queue(20);
//一個生產者、兩個消費者
if(CreateThread(NULL,0,produce,&queue,0,&write_data)==NULL)
return -1;
if(CreateThread(NULL,0,consume,&queue,0,&read_data)==NULL)
return -1;
if(CreateThread(NULL,0,consume,&queue,0,&read_data1)==NULL)
return -1;
char ch;
while(1)
{
ch = getchar(); //press "e" to exit
if(ch == 'e') break;
}
printf("Program ends successfully\n");
return 0;
}