Windows下一个并发阻塞队列(BlockingQueue)

来源:互联网 发布:日本皇族知乎 编辑:程序博客网 时间:2024/05/21 09:21
Windows下一个带有大小限制的并发阻塞队列,实现的比较简单。
[cpp] view plaincopy
  1. #ifndef BLOCKINGQUEUE_H_  
  2. #define BLOCKINGQUEUE_H_  
  3.   
  4. #include <queue>  
  5. #include <windows.h>  
  6. using namespace std;  
  7.   
  8. template <typename T>  
  9. class BoundedBlockingQueue   
  10. {   
  11. public:   
  12.     BoundedBlockingQueue(int size) : maxSize(size)   
  13.     {  
  14.         _lock = CreateMutex(NULL,false,NULL);  
  15.         _rsem = CreateSemaphore(NULL,0,size,NULL);  
  16.         _wsem = CreateSemaphore(NULL,size,size,NULL);  
  17.     }   
  18.     ~BoundedBlockingQueue()   
  19.     {   
  20.         CloseHandle(_lock);  
  21.         CloseHandle(_rsem);  
  22.         CloseHandle(_wsem);  
  23.     }   
  24.     void push(const T& data);  
  25.     T pop();  
  26.     bool empty()  
  27.     {  
  28.         WaitForSingleObject(_lock,INFINITE);  
  29.         bool is_empty = _array.empty();  
  30.         ReleaseMutex(_lock);  
  31.         return is_empty;  
  32.     }  
  33. private:   
  34.     deque<T> _array;  
  35.     int maxSize;  
  36.     HANDLE _lock;  
  37.     HANDLE _rsem, _wsem;  
  38. };  
  39.   
  40. template <typename T>  
  41. void BoundedBlockingQueue <T>::push(const T& value )   
  42. {   
  43.     WaitForSingleObject(_wsem,INFINITE);  
  44.     WaitForSingleObject(_lock,INFINITE);  
  45.     _array.push_back(value);  
  46.     ReleaseMutex(_lock);  
  47.     ReleaseSemaphore(_rsem,1,NULL);  
  48. }  
  49.   
  50. template <typename T>  
  51. T BoundedBlockingQueue<T>::pop()   
  52. {   
  53.     WaitForSingleObject(_rsem,INFINITE);  
  54.     WaitForSingleObject(_lock,INFINITE);  
  55.     T _temp = _array.front();  
  56.     _array.pop_front();  
  57.     ReleaseMutex(_lock);  
  58.     ReleaseSemaphore(_wsem,1,NULL);  
  59.     return _temp;  
  60. }  
  61.   
  62. #endif  

主函数调用测试:一个生产者、两个消费者使用这个队列进行测试。

[cpp] view plaincopy
  1. #include "BlockingQueue.h"  
  2. #include <windows.h>  
  3. #include <iostream>  
  4. using namespace std;  
  5.   
  6. bool is_over = false;  
  7.   
  8. DWORD WINAPI produce(LPVOID lppara)  
  9. {  
  10.     BoundedBlockingQueue<int> *queue = (BoundedBlockingQueue<int> *)lppara;  
  11.   
  12.     while(1)  
  13.     {  
  14.         for(int i=1; i<=50; ++i)  
  15.         {  
  16.             queue->push(i);  
  17.             cout<<GetCurrentThreadId()<<" put a data: "<<i<<endl;  
  18.             Sleep(10); //producer is fast  
  19.         }  
  20.         is_over = true;  
  21.         break;  
  22.     }  
  23.     return NULL;  
  24. }  
  25.   
  26. DWORD WINAPI consume(LPVOID lppara)  
  27. {  
  28.     BoundedBlockingQueue<int> *queue = (BoundedBlockingQueue<int> *)lppara;  
  29.   
  30.     while(1)  
  31.     {  
  32.         int d = queue->pop();  
  33.         cout<<GetCurrentThreadId()<<" get data: "<<d<<endl;  
  34.         //double check  
  35.         if(is_over && queue->empty())  
  36.         {  
  37.             cout<<"OVER!"<<endl;  
  38.             break;  
  39.         }  
  40.         Sleep(10); //consumer is slow  
  41.     }  
  42.     return NULL;  
  43. }  
  44.   
  45. int main()  
  46. {  
  47.     DWORD write_data;  
  48.     DWORD read_data;  
  49.     DWORD read_data1;  
  50.   
  51.     BoundedBlockingQueue<int> queue(20);  
  52.   
  53.     //一个生产者、两个消费者  
  54.     if(CreateThread(NULL,0,produce,&queue,0,&write_data)==NULL)  
  55.         return -1;  
  56.     if(CreateThread(NULL,0,consume,&queue,0,&read_data)==NULL)  
  57.         return -1;  
  58.     if(CreateThread(NULL,0,consume,&queue,0,&read_data1)==NULL)  
  59.         return -1;  
  60.   
  61.     char ch;  
  62.     while(1)  
  63.     {  
  64.         ch = getchar(); //press "e" to exit  
  65.         if(ch == 'e'break;  
  66.     }  
  67.   
  68.     printf("Program ends successfully\n");  
  69.   
  70.     return 0;  
  71. }  
0 0
原创粉丝点击