日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

秒杀多线程第十六篇 多线程十大经典案例之一 双线程读写队列数据

發(fā)布時間:2024/4/11 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 秒杀多线程第十六篇 多线程十大经典案例之一 双线程读写队列数据 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文配套程序下載地址為:http://download.csdn.net/detail/morewindows/5136035

轉(zhuǎn)載請標(biāo)明出處,原文地址:http://blog.csdn.net/morewindows/article/details/8646902

歡迎關(guān)注微博:http://weibo.com/MoreWindows

?

在《秒殺多線程系列》的前十五篇中介紹多線程的相關(guān)概念,多線程同步互斥問題《秒殺多線程第四篇一個經(jīng)典的多線程同步問題》及解決多線程同步互斥的常用方法——關(guān)鍵段事件互斥量信號量讀寫鎖。為了讓大家更加熟練運用多線程,將會有十篇文章來講解十個多線程使用案例,相信看完這十篇后會讓你能更加游刃有余的使用多線程。

首先來看第一篇——《秒殺多線程第十六篇 多線程十大經(jīng)典案例之一 雙線程讀寫隊列數(shù)據(jù)》

《多線程十大經(jīng)典案例之一雙線程讀寫隊列數(shù)據(jù)》案例描述:

MFC對話框中一個按鈕的響應(yīng)函數(shù)實現(xiàn)兩個功能:
顯示數(shù)據(jù)同時處理數(shù)據(jù),因此開兩個線程,一個線程顯示數(shù)據(jù)(開了一個定時器,響應(yīng)WM_TIMER消息按照一定時間間隔向TeeChart圖表添加數(shù)據(jù)并顯示)同時在隊列隊尾添加數(shù)據(jù),另一個線程從該隊列隊頭去數(shù)據(jù)來處理。

本案例來源于http://bbs.csdn.net/topics/390383114,感謝hehening88提供題目,特此鳴謝。

下面就來解決這個案例。先來分析下。

?

《多線程十大經(jīng)典案例之一雙線程讀寫隊列數(shù)據(jù)》案例分析:

這個案例是一個線程向隊列中的隊列頭部讀取數(shù)據(jù),一個線程向隊列中的隊列尾部寫入數(shù)據(jù)。看起來很像讀者寫者問題(見《秒殺多線程第十一篇讀者寫者問題》和《秒殺多線程第十四篇讀者寫者問題繼讀寫鎖SRWLock》),但其實不然,如果將隊列看成緩沖區(qū),這個案例明顯是個生產(chǎn)者消費者問題(見《秒殺多線程第十篇生產(chǎn)者消費者問題》)。因此我們仿照生產(chǎn)者消費者的思路來具體分析下案例中的“等待”情況:

??? 1.?????當(dāng)隊列為空時,讀取數(shù)據(jù)線程必須等待寫入數(shù)據(jù)向隊列中寫入數(shù)據(jù)。也就是說當(dāng)隊列為空時,讀取數(shù)據(jù)線程要等待隊列中有數(shù)據(jù)

??? 2.?????當(dāng)隊列滿時,寫入數(shù)據(jù)線程必須等待讀取數(shù)據(jù)線程向隊列中讀取數(shù)據(jù)。也就是說當(dāng)隊列滿時,寫入數(shù)據(jù)線程要等待隊列中有空位

訪問隊列時,需要互斥嗎?這將依賴于隊列的數(shù)據(jù)結(jié)構(gòu)實現(xiàn),如果使用STL中的vector,由于vector會動態(tài)增長。因此要做互斥保護(hù)。如果使用循環(huán)隊列,那么讀取數(shù)據(jù)線程擁有讀取指針,寫入數(shù)據(jù)線程擁有寫入指針,各自將訪問隊列中不同位置上的數(shù)據(jù),因此不用進(jìn)行互斥保護(hù)。

分析完畢后,再來考慮使用什么樣的數(shù)據(jù)結(jié)構(gòu),同樣依照《秒殺多線程第十篇生產(chǎn)者消費者問題》中的做法。使用兩個信號量,一個來記錄循環(huán)隊列中空位的個數(shù),一個來記錄循環(huán)隊列中產(chǎn)品的個數(shù)(非空位個數(shù))。代碼非常容易寫出,下面給出完整的源代碼。

代碼中的信號量相關(guān)函數(shù)可以參考《秒殺多線程第八篇經(jīng)典線程同步信號量Semaphore》,代碼中的SetConsoleColor是用來改變控制臺的文字顏色,具體可以參考《VC?控制臺顏色設(shè)置》。

?

《多線程十大經(jīng)典案例之一雙線程讀寫隊列數(shù)據(jù)》完整代碼:

[cpp]?view plaincopy
  • //秒殺多線程第十六篇?多線程十大經(jīng)典案例之一?雙線程讀寫隊列數(shù)據(jù)??
  • //http://blog.csdn.net/MoreWindows/article/details/8646902??
  • #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;??
  • //關(guān)鍵段?用于保證互斥的在屏幕上輸出??
  • CRITICAL_SECTION?g_cs;??
  • //信號量?g_hEmpty表示隊列中空位?g_hFull表示隊列中非空位??
  • HANDLE?????g_hEmpty,?g_hFull;??
  • //設(shè)置控制臺輸出顏色??
  • BOOL?SetConsoleColor(WORD?wAttributes)??
  • {??
  • ????HANDLE?hConsole?=?GetStdHandle(STD_OUTPUT_HANDLE);??
  • ????if?(hConsole?==?INVALID_HANDLE_VALUE)??
  • ????????return?FALSE;?????
  • ????return?SetConsoleTextAttribute(hConsole,?wAttributes);??
  • }??
  • //讀數(shù)據(jù)線程函數(shù)??
  • 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("從隊列中讀數(shù)據(jù)%d\n",?nData);??
  • ????????LeaveCriticalSection(&g_cs);??
  • ????????Sleep(rand()?%?300);??
  • ????????ReleaseSemaphore(g_hEmpty,?1,?NULL);??
  • ????}??
  • ????return?0;??
  • }??
  • //寫數(shù)據(jù)線程函數(shù)??
  • 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("????將數(shù)據(jù)%d寫入隊列\(zhòng)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("?????秒殺多線程第十六篇?多線程十大經(jīng)典案例?雙線程讀寫隊列數(shù)據(jù)\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;??
  • }??
  • ?

    《多線程十大經(jīng)典案例之一雙線程讀寫隊列數(shù)據(jù)》運行結(jié)果:

    程序運行結(jié)果如下:

    本文配套程序下載地址為:http://download.csdn.net/detail/morewindows/5136035

    轉(zhuǎn)載請標(biāo)明出處,原文地址:http://blog.csdn.net/morewindows/article/details/8646902

    歡迎關(guān)注微博:http://weibo.com/MoreWindows

    超強干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生

    總結(jié)

    以上是生活随笔為你收集整理的秒杀多线程第十六篇 多线程十大经典案例之一 双线程读写队列数据的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。