生活随笔
收集整理的這篇文章主要介紹了
秒杀多线程第十六篇 多线程十大经典案例之一 双线程读写队列数据
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本文配套程序下載地址為:http://download.csdn.net/detail/morewindows/5136035
轉載請標明出處,原文地址:http://blog.csdn.net/morewindows/article/details/8646902
歡迎關注微博:http://weibo.com/MoreWindows
?
在《秒殺多線程系列》的前十五篇中介紹多線程的相關概念,多線程同步互斥問題《秒殺多線程第四篇一個經典的多線程同步問題》及解決多線程同步互斥的常用方法——關鍵段、事件、互斥量、信號量、讀寫鎖。為了讓大家更加熟練運用多線程,將會有十篇文章來講解十個多線程使用案例,相信看完這十篇后會讓你能更加游刃有余的使用多線程。
首先來看第一篇——《秒殺多線程第十六篇 多線程十大經典案例之一 雙線程讀寫隊列數據》
《多線程十大經典案例之一雙線程讀寫隊列數據》案例描述:
MFC對話框中一個按鈕的響應函數實現兩個功能:
顯示數據同時處理數據,因此開兩個線程,一個線程顯示數據(開了一個定時器,響應WM_TIMER消息按照一定時間間隔向TeeChart圖表添加數據并顯示)同時在隊列隊尾添加數據,另一個線程從該隊列隊頭去數據來處理。
本案例來源于http://bbs.csdn.net/topics/390383114,感謝hehening88提供題目,特此鳴謝。
下面就來解決這個案例。先來分析下。
?
《多線程十大經典案例之一雙線程讀寫隊列數據》案例分析:
這個案例是一個線程向隊列中的隊列頭部讀取數據,一個線程向隊列中的隊列尾部寫入數據。看起來很像讀者寫者問題(見《秒殺多線程第十一篇讀者寫者問題》和《秒殺多線程第十四篇讀者寫者問題繼讀寫鎖SRWLock》),但其實不然,如果將隊列看成緩沖區,這個案例明顯是個生產者消費者問題(見《秒殺多線程第十篇生產者消費者問題》)。因此我們仿照生產者消費者的思路來具體分析下案例中的“等待”情況:
??? 1.?????當隊列為空時,讀取數據線程必須等待寫入數據向隊列中寫入數據。也就是說當隊列為空時,讀取數據線程要等待隊列中有數據。
??? 2.?????當隊列滿時,寫入數據線程必須等待讀取數據線程向隊列中讀取數據。也就是說當隊列滿時,寫入數據線程要等待隊列中有空位。
在訪問隊列時,需要互斥嗎?這將依賴于隊列的數據結構實現,如果使用STL中的vector,由于vector會動態增長。因此要做互斥保護。如果使用循環隊列,那么讀取數據線程擁有讀取指針,寫入數據線程擁有寫入指針,各自將訪問隊列中不同位置上的數據,因此不用進行互斥保護。
分析完畢后,再來考慮使用什么樣的數據結構,同樣依照《秒殺多線程第十篇生產者消費者問題》中的做法。使用兩個信號量,一個來記錄循環隊列中空位的個數,一個來記錄循環隊列中產品的個數(非空位個數)。代碼非常容易寫出,下面給出完整的源代碼。
代碼中的信號量相關函數可以參考《秒殺多線程第八篇經典線程同步信號量Semaphore》,代碼中的SetConsoleColor是用來改變控制臺的文字顏色,具體可以參考《VC?控制臺顏色設置》。
?
《多線程十大經典案例之一雙線程讀寫隊列數據》完整代碼:
[cpp]?view plaincopy
?? ?? #include?<stdio.h>?? #include?<process.h>?? #include?<windows.h>?? #include?<time.h>?? const?int?QUEUE_LEN?=?5;?? int?g_arrDataQueue[QUEUE_LEN];?? int?g_i,?g_j,?g_nDataNum;?? ?? CRITICAL_SECTION?g_cs;?? ?? HANDLE?????g_hEmpty,?g_hFull;?? ?? BOOL?SetConsoleColor(WORD?wAttributes)?? {?? ????HANDLE?hConsole?=?GetStdHandle(STD_OUTPUT_HANDLE);?? ????if?(hConsole?==?INVALID_HANDLE_VALUE)?? ????????return?FALSE;????? ????return?SetConsoleTextAttribute(hConsole,?wAttributes);?? }?? ?? unsigned?int?__stdcall?ReaderThreadFun(PVOID?pM)?? {?? ????int?nData?=?0;?? ????while?(nData?<?20)?? ????{?? ????????WaitForSingleObject(g_hFull,?INFINITE);?? ????????nData?=?g_arrDataQueue[g_i];?? ????????g_i?=?(g_i?+?1)?%?QUEUE_LEN;?? ????????EnterCriticalSection(&g_cs);?? ????????printf("從隊列中讀數據%d\n",?nData);?? ????????LeaveCriticalSection(&g_cs);?? ????????Sleep(rand()?%?300);?? ????????ReleaseSemaphore(g_hEmpty,?1,?NULL);?? ????}?? ????return?0;?? }?? ?? unsigned?int?__stdcall?WriterThreadFun(PVOID?pM)?? {?? ????int?nData?=?0;?? ????while?(nData?<?20)?? ????{?? ????????WaitForSingleObject(g_hEmpty,?INFINITE);?? ????????g_arrDataQueue[g_j]?=?++nData;?? ????????g_j?=?(g_j?+?1)?%?QUEUE_LEN;?? ????????EnterCriticalSection(&g_cs);?? ????????SetConsoleColor(FOREGROUND_GREEN);?? ????????printf("????將數據%d寫入隊列\n",?nData);?? ????????SetConsoleColor(FOREGROUND_RED?|?FOREGROUND_GREEN?|?FOREGROUND_BLUE);?? ????????LeaveCriticalSection(&g_cs);?? ????????Sleep(rand()?%?300);?? ????????ReleaseSemaphore(g_hFull,?1,?NULL);?? ????}?? ????return?0;?? }?? int?main()?? {?? ????printf("?????秒殺多線程第十六篇?多線程十大經典案例?雙線程讀寫隊列數據\n");?? ????printf("?-?by?MoreWindows(?http://blog.csdn.net/MoreWindows/article/details/8646902?)?-\n\n");?? ?????? ????InitializeCriticalSection(&g_cs);?? ????g_hEmpty?=?CreateSemaphore(NULL,?QUEUE_LEN,?QUEUE_LEN,?NULL);?? ????g_hFull?=?CreateSemaphore(NULL,?0,?QUEUE_LEN,?NULL);?? ?????? ????srand(time(NULL));?? ????g_i?=?g_j?=?0;?? ????HANDLE?hThread[2];?? ????hThread[0]?=?(HANDLE)_beginthreadex(NULL,?0,?ReaderThreadFun,?NULL,?0,?NULL);?? ????hThread[1]?=?(HANDLE)_beginthreadex(NULL,?0,?WriterThreadFun,?NULL,?0,?NULL);?? ?????? ????WaitForMultipleObjects(2,?hThread,?TRUE,?INFINITE);?? ?????? ????for?(int?i?=?0;?i?<?2;?i++)?? ????????CloseHandle(hThread[i]);?? ????CloseHandle(g_hEmpty);?? ????CloseHandle(g_hFull);?? ????DeleteCriticalSection(&g_cs);?? ????return?0;?? }??
?
《多線程十大經典案例之一雙線程讀寫隊列數據》運行結果:
程序運行結果如下:
本文配套程序下載地址為:http://download.csdn.net/detail/morewindows/5136035
轉載請標明出處,原文地址:http://blog.csdn.net/morewindows/article/details/8646902
歡迎關注微博:http://weibo.com/MoreWindows
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生
總結
以上是生活随笔為你收集整理的秒杀多线程第十六篇 多线程十大经典案例之一 双线程读写队列数据的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。