• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-3  評論-5  文章-13  trackbacks-0

            --------------------------------------------------------------------------------
            標題: 在Win32平臺中,多讀單寫鎖如何實現?
            作者: 葉飛虎
            日期: 2004.03.17
            --------------------------------------------------------------------------------

               在多線程編程中,讀寫鎖主要應用于寫數據相對比較少,而讀比較多,同時要求并發性
            比較高的時候。

            現給出讀寫鎖代碼,如下:

             

              1 /* TKYLockRW - 多讀單寫鎖類 */
              2 
              3 class TKYLockRW
              4 {
              5 public:
              6    TKYLockRW();
              7    virtual ~TKYLockRW();
              8 
              9    bool              LockRead();
             10    bool              LockWrite();
             11 
             12    bool              TryLockRead();
             13    bool              TryLockWrite();
             14 
             15    void              UnlockRead();
             16    void              UnlockWrite();
             17 
             18 private:
             19    void              Lock()            { EnterCriticalSection(&FRWLock); }
             20    void              Unlock()          { LeaveCriticalSection(&FRWLock); }
             21 
             22    inline void       SetReadSignal();
             23    inline void       SetWriteSignal();
             24 
             25 private:
             26    CRITICAL_SECTION  FRWLock;
             27    HANDLE            FReaderEvent;
             28    HANDLE            FWriterEvent;
             29    long              FReadingCount;
             30    long              FWritingCount;
             31    long              FWaitingReadCount;
             32    long              FWaitingWriteCount;
             33 };
             34 
             35 /* TKYLockRW - 多讀單寫鎖類 */
             36 
             37 // ---------------- 構造函數和析構函數 ----------------
             38 // 構造函數
             39 TKYLockRW::TKYLockRW()
             40 {
             41    // 初始化
             42    FReadingCount     = 0;
             43    FWritingCount     = 0;
             44    FWaitingReadCount = 0;
             45    FWaitingWriteCount= 0;
             46 
             47    // 創建臨界區和讀寫者事件
             48    InitializeCriticalSection(&FRWLock);
             49    FReaderEvent      = CreateEvent(NULL, FALSE, FALSE, NULL);
             50    FWriterEvent      = CreateEvent(NULL, FALSE, FALSE, NULL);
             51 }
             52 
             53 // 析構函數
             54 TKYLockRW::~TKYLockRW()
             55 {
             56    // 置釋放標志
             57    Lock();
             58    bool bWaiting = (FReadingCount > 0|| (FWritingCount == 1)
             59                                        || (FWaitingReadCount > 0)
             60                                        || (FWaitingWriteCount > 0);
             61    FReadingCount = -1;
             62    Unlock();
             63 
             64    // 等待一會兒
             65    if (bWaiting)
             66       Sleep(10);
             67 
             68    // 釋放臨界區和讀寫者事件
             69    CloseHandle(FReaderEvent);
             70    CloseHandle(FWriterEvent);
             71    DeleteCriticalSection(&FRWLock);
             72 }
             73 
             74 // ---------------- 私有方法 ----------------
             75 // 設置讀信號
             76 inline void TKYLockRW::SetReadSignal()
             77 {
             78    // FWritingCount 作為讀信號廣播的個數
             79    if (FWritingCount == 0)
             80       FWritingCount = -FWaitingReadCount;
             81 
             82    // 是否需要繼續廣播
             83    if (FWritingCount < 0)
             84    {
             85       FWritingCount++;
             86       FReadingCount++;
             87       FWaitingReadCount--;
             88 
             89       SetEvent(FReaderEvent);
             90    }
             91 }
             92 
             93 // 設置寫信號
             94 inline void TKYLockRW::SetWriteSignal()
             95 {
             96    FWritingCount = 1;
             97    FWaitingWriteCount--;
             98 
             99    SetEvent(FWriterEvent);
            100 }
            101 
            102 // ---------------- 公有方法 ----------------
            103 // 讀加鎖
            104 bool TKYLockRW::LockRead()
            105 {
            106    bool result   = true;
            107    bool bWaiting = false;
            108 
            109    // 讀數加 1
            110    Lock();
            111    if (FReadingCount == -1)      // 釋放標志
            112       result = false;
            113    else if ((FWritingCount == 1|| (FWaitingWriteCount > 0))
            114    {
            115       FWaitingReadCount++;
            116       bWaiting = true;
            117    }
            118    else
            119       FReadingCount++;
            120    Unlock();
            121 
            122    // 判斷是否等待讀信號
            123    if (bWaiting)
            124    {
            125       // 等待讀信號
            126       result = (WaitForSingleObject(FReaderEvent, INFINITE) == WAIT_OBJECT_0);
            127 
            128       if (result)
            129       {
            130          // 若廣播個數不為零則繼續置信號
            131          Lock();
            132          if (FWritingCount < 0)
            133             SetReadSignal();
            134          Unlock();
            135       }
            136    }
            137 
            138    // 返回結果
            139    return result;
            140 }
            141 
            142 // 寫加鎖
            143 bool TKYLockRW::LockWrite()
            144 {
            145    bool result   = true;
            146    bool bWaiting = false;
            147 
            148    // 寫數置 1
            149    Lock();
            150    if (FReadingCount == -1)      // 釋放標志
            151       result = false;
            152    else if ((FWritingCount == 1|| (FReadingCount > 0))
            153    {
            154       FWaitingWriteCount++;
            155       bWaiting = true;
            156    }
            157    else
            158       FWritingCount = 1;
            159    Unlock();
            160 
            161    // 判斷是否等待寫信號
            162    if (bWaiting)
            163       result = (WaitForSingleObject(FWriterEvent, INFINITE) == WAIT_OBJECT_0);
            164 
            165    // 返回結果
            166    return result;
            167 }
            168 
            169 // 讀試著加鎖
            170 bool TKYLockRW::TryLockRead()
            171 {
            172    bool result = true;
            173 
            174    // 讀數加 1
            175    Lock();
            176    if ((FReadingCount == -1|| (FWritingCount == 1)
            177                              || (FWaitingWriteCount > 0))
            178       result = false;
            179    else
            180       FReadingCount++;
            181    Unlock();
            182 
            183    // 返回結果
            184    return result;
            185 }
            186 
            187 // 寫試著加鎖
            188 bool TKYLockRW::TryLockWrite()
            189 {
            190    bool result = true;
            191 
            192    // 寫數置 1
            193    Lock();
            194    if ((FReadingCount == -1|| (FWritingCount == 1)
            195                              || (FReadingCount > 0))
            196       result = false;
            197    else
            198       FWritingCount = 1;
            199    Unlock();
            200 
            201    // 返回結果
            202    return result;
            203 }
            204 
            205 // 讀解鎖
            206 void TKYLockRW::UnlockRead()
            207 {
            208    Lock();
            209    if (FReadingCount > 0)
            210    {
            211       // 讀數減 1
            212       FReadingCount--;
            213 
            214       // 置讀/寫信號
            215       if (FReadingCount == 0)
            216       {
            217          if (FWaitingWriteCount > 0)
            218             SetWriteSignal();
            219          else
            220             SetReadSignal();
            221       }
            222    }
            223    Unlock();
            224 }
            225 
            226 // 寫解鎖
            227 void TKYLockRW::UnlockWrite()
            228 {
            229    Lock();
            230    if (FWritingCount == 1)
            231    {
            232       // 寫數置 0
            233       FWritingCount = 0;
            234 
            235       // 置讀/寫信號
            236       if (FWaitingWriteCount > FWaitingReadCount)
            237          SetWriteSignal();
            238       else
            239          SetReadSignal();
            240    }
            241    Unlock();
            242 }
            243 
            244 

             

            posted on 2011-05-22 11:22 Kyee Ye 閱讀(652) 評論(0)  編輯 收藏 引用 所屬分類: C++類庫KYLib 源碼
            97久久精品国产精品青草| 亚洲国产成人久久一区久久| 久久精品国产色蜜蜜麻豆| 久久精品国产清自在天天线| 日本国产精品久久| 久久精品国产日本波多野结衣| 久久久久人妻精品一区| 久久亚洲国产午夜精品理论片| 久久精品国产99久久香蕉| 77777亚洲午夜久久多人| 久久国产亚洲精品麻豆| 99久久免费国产精品特黄| 久久精品99久久香蕉国产色戒| 岛国搬运www久久| 久久精品国产亚洲精品2020| 久久伊人色| 69久久精品无码一区二区| 亚洲综合久久久| 久久93精品国产91久久综合| 久久夜色精品国产噜噜噜亚洲AV| 久久久艹| 国产精久久一区二区三区| 久久久无码人妻精品无码| 亚洲乱码日产精品a级毛片久久| 久久精品视频网| 久久久久亚洲Av无码专| 久久婷婷五月综合色奶水99啪| 国产精品gz久久久| 久久免费高清视频| 久久精品国产精品国产精品污| 亚洲AV无一区二区三区久久 | 久久亚洲sm情趣捆绑调教| 一本一道久久精品综合| 狠狠久久亚洲欧美专区| 久久久久久亚洲精品成人| 伊人久久大香线蕉综合影院首页 | 国产香蕉久久精品综合网| 久久久久亚洲AV无码去区首| 久久天天躁狠狠躁夜夜2020| 色天使久久综合网天天| 亚洲国产精品无码久久九九|