下面我將對這兩個問題和大家一起探討一下。相信大家對生產者消費者問題並不生疏。在讀書的時候我們采用系統體提供的p,v解決,這是對同一臨界區資源同時進行讀寫需要的保護措施,本工程使用緩沖隊列,故不需要對臨界區進行加鎖 。馬上我會實現雙緩存的版本。在此版本中我會實現對臨界區的加減鎖。
讀取的數據要存儲到相應的數據結構中,可以有很多種選擇,比如存成任務緩沖隊列(以鏈表實現)其中大部分工程使用循環隊列用於一寫多讀,寫線程將數據寫入隊列,讀線程從隊列中讀取。或者實現雙緩存方法,即寫線程寫滿一個緩存讀線程來取數據同時寫線程將數據寫入另一個緩存。
具體的實現如下:
鏈表的節點聲明如下:
typedef strUCt NODE
{
int Buffer[MAX_BUFFER_SIZE];
long Counters;
bool ReadEnable;
NODE * pNext;
}NODE;
其中數組Buffer[]用來存放采集數據。Counters用來描述有多少個讀線程曾對節點進行訪問。假如所有讀線程都訪問過此節點,即可將此節點刪除!ReadEnable表示其節點是否可讀。
鏈表的聲明如下:
typedef struct LIST
{
NODE * pReadPtr;
NODE * pWritePtr;
NODE * pHeadPtr;
}LIST;
其中pReadPtr為指向可讀節點的指針,pWritePtr為指向可寫節點的指針。其中pReadPtr在pWritePtr的後面,也就是寫指針不能超過讀指針。pHeadPtr指向鏈表中第一個節點的指針。
我使用一個寫線程兩個讀線程,也可以實現兩個以上的讀線程。朋友們可以試一下只需要修改list中Counters就行了。
DWord WINAPI ReaderOne(void * pVoid);
DWORD WINAPI ReaderTwo(void * pVoid);
DWORD WINAPI WriterUnique(void * pVoid);
在WriterUnique我采用動態分配節點,同時模擬數據采集填充NODE的buffer數組。當然要對寫線程進行加鎖保護。在ReaderOne和ReaderTwo中對鏈表中的節點進行訪問並顯示在對話框中。
注重的問題:
1, 因為節點是動態分配內存,所以new之後一定要delete否則內存就會被程序慢慢吃掉
2,加鎖之後一定要解鎖否則就會引起死鎖問題。
3,首先點擊“啟動寫線程”然後點擊“啟動讀線程 ”程序在退出之前點擊“結束寫線程“就可觀察到執行效果。