• boost 线程安全队列


    1. // QueueImplementation.cpp : Defines the entry point for the console application.  
    2. //  
    3. #include "stdafx.h"  
    4. #include <windows.h>  
    5. #include <iostream>  
    6. #include <queue>  
    7. #include <string>  
    8. #include <process.h>  
    9. using namespace std;  
    10. struct DataBlock  
    11. {  
    12.     string m_szText;    //sample data  
    13. };  
    14. class CDataQueue  
    15. {  
    16. private:  
    17.     queue<DataBlock>  m_oQueue;   //contains the actual data  
    18.     CRITICAL_SECTION        m_csData;   //to synchroize access to m_csData among multiple threads  
    19.     HANDLE                  m_hEvent;   //for signalling presence of absence of data  
    20. public:  
    21.     //create a manual reset event initially signalled.  
    22.     //This event will be signalled and shall remain so whenever there is data in the queue and  
    23.     //it shall be reset as long as queue is empty  
    24.     CDataQueue()  
    25.     {   
    26.         InitializeCriticalSection(&m_csData);  
    27.         m_hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);  
    28.     };  
    29.     //close the event handle  
    30.     ~CDataQueue()  
    31.     {   
    32.         DeleteCriticalSection(&m_csData);  
    33.         CloseHandle(m_hEvent);  
    34.     };  
    35.     //public methods to Push data to queue  
    36.     void Push(DataBlock& oNewData)  
    37.     {  
    38.         EnterCriticalSection(&m_csData);  
    39.         //push new element to queue  
    40.         m_oQueue.push(oNewData);  
    41.         //now that there is atleast one element, set the event  
    42.         SetEvent(m_hEvent);  
    43.         LeaveCriticalSection(&m_csData);  
    44.     };  
    45.     //public methods to Pop data from queue  
    46.     DataBlock Pop()  
    47.     {  
    48.         EnterCriticalSection(&m_csData);  
    49.         //first get the topmost data block  
    50.         DataBlock popData = m_oQueue.front();  
    51.         //next remove it from queue  
    52.         m_oQueue.pop();  
    53.         //now, check for new size.. if no more elements in queue  
    54.         //reset the event  
    55.         if(!m_oQueue.size())  
    56.             ResetEvent(m_hEvent);  
    57.         LeaveCriticalSection(&m_csData);  
    58.         return popData;  
    59.     };  
    60.     //helper method to get the event handle  
    61.     HANDLE GetEvent(){return m_hEvent;};  
    62. };  
    63. CDataQueue g_oQueue;  
    64. HANDLE     g_hExitEvent;  
    65. unsigned __stdcall ProcessData (void * )  
    66. {  
    67.     HANDLE hEvents[] = { g_hExitEvent, g_oQueue.GetEvent()};  
    68.     DWORD dwRet;  
    69.     BOOL bContinue = TRUE;  
    70.     while(bContinue)  
    71.     {  
    72.         dwRet = WaitForMultipleObjects(sizeof(hEvents)/sizeof(hEvents[0]),hEvents,FALSE,INFINITE);  
    73.         switch(dwRet)  
    74.         {  
    75.         case WAIT_OBJECT_0 :  
    76.             {  
    77.                 //exit signalled.. time to quit the thread  
    78.                 bContinue = FALSE;  
    79.             }  
    80.             break;  
    81.         case WAIT_OBJECT_0 + 1:  
    82.             {  
    83.                 //some data got..   
    84.                 DataBlock oData = g_oQueue.Pop();  
    85.                 //echo data to screen  
    86.                 cout << "Data typed in is .. " << oData.m_szText << "/n";  
    87.             }  
    88.             break;  
    89.         default:break;  
    90.         }  
    91.     }  
    92.     return 0;  
    93. }  
    94. int main(int argc, char* argv[])  
    95. {  
    96.     DWORD dwThreadID = 0;  
    97.     HANDLE hThread = NULL;  
    98.     //create an event to signal worker thread to exit  
    99.     g_hExitEvent = CreateEvent(NULL,TRUE,FALSE,NULL);//not signalled initially..   
    100.     //spawn a thread for processing the input  
    101.     hThread = (HANDLE)_beginthreadex(NULL,0,ProcessData,NULL,0,(unsigned int *)&dwThreadID);  
    102.     if(hThread)  
    103.     {  
    104.         cout << "enter sentence to process /nOR /nenter /"exit/" to quit/n";  
    105.         do  
    106.         {  
    107.             DataBlock oData;  
    108.             cin >> oData.m_szText;  
    109.             //if exit typed in.. quit  
    110.             if(0 == oData.m_szText.compare("exit"))  
    111.                 break;  
    112.             g_oQueue.Push(oData);  
    113.         }  
    114.         while(1);  
    115.         //time to close ..set the exit event  
    116.         SetEvent(g_hExitEvent);  
    117.         //wait for worker thread to close  
    118.         WaitForSingleObject(hThread,INFINITE);  
    119.         //close the thread handle  
    120.         CloseHandle(hThread);  
    121.     }  
    122.       
    123.     CloseHandle(g_hExitEvent);  
    124.       
    125.     return 0;  
    126. }  
     
    1. template<typename Data>  
    2. class concurrent_queue  
    3. {  
    4. private:  
    5.     std::queue<Data> the_queue;  
    6.     mutable boost::mutex the_mutex;  
    7.     boost::condition_variable the_condition_variable;  
    8. public:  
    9.     void push(Data const& data)  
    10.     {  
    11.         boost::mutex::scoped_lock lock(the_mutex);  
    12.         the_queue.push(data);  
    13.         lock.unlock();  
    14.         the_condition_variable.notify_one();  
    15.     }  
    16.     bool empty() const  
    17.     {  
    18.         boost::mutex::scoped_lock lock(the_mutex);  
    19.         return the_queue.empty();  
    20.     }  
    21.     bool try_pop(Data& popped_value)  
    22.     {  
    23.         boost::mutex::scoped_lock lock(the_mutex);  
    24.         if(the_queue.empty())  
    25.         {  
    26.             return false;  
    27.         }  
    28.           
    29.         popped_value=the_queue.front();  
    30.         the_queue.pop();  
    31.         return true;  
    32.     }  
    33.     void wait_and_pop(Data& popped_value)  
    34.     {  
    35.         boost::mutex::scoped_lock lock(the_mutex);  
    36.         while(the_queue.empty())  
    37.         {  
    38.             the_condition_variable.wait(lock);  
    39.         }  
    40.           
    41.         popped_value=the_queue.front();  
    42.         the_queue.pop();  
    43.     }  
    44. };  
     
  • 相关阅读:
    svn中出现各种感叹号说明
    Oracle“记录被另一个用户锁住” 无法更新删除的解决办法
    C/C++中extern关键字详解
    Oracle创建视图view权限不足问题剖析
    和菜鸟一起学linux之常见错误的解决和常用命令
    万能数据库查询分析器使用技巧之(十一)
    orale中如何获取当前月份?
    “刘易斯拐点”后劳动力市场中的信任与有效性
    “微”力无穷:企业微信营销全攻略
    2小时精通金数据
  • 原文地址:https://www.cnblogs.com/rainbowzc/p/4294452.html
Copyright © 2020-2023  润新知