zoukankan      html  css  js  c++  java
  • 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. };  
     
  • 相关阅读:
    AIMS 2013中的性能报告工具不能运行的解决办法
    读懂AIMS 2013中的性能分析报告
    在线研讨会网络视频讲座 方案设计利器Autodesk Infrastructure Modeler 2013
    Using New Profiling API to Analyze Performance of AIMS 2013
    Map 3D 2013 新功能和新API WebCast视频下载
    为Autodesk Infrastructure Map Server(AIMS) Mobile Viewer创建自定义控件
    ADN新开了云计算Cloud和移动计算Mobile相关技术的博客
    JavaScript修改css样式style
    文本编辑神器awk
    jquery 开发总结1
  • 原文地址:https://www.cnblogs.com/rainbowzc/p/4294452.html
Copyright © 2011-2022 走看看