基於windows api實現的共用鎖定/獨佔鎖

來源:互聯網
上載者:User

標籤:windows 線程同步 鎖 共用鎖定 排   windows   c   效能   

眾所周知,windows平台上實現線程同步,或者說資源的加鎖與解鎖的方法有核心事件、臨界區、互斥量、訊號量,甚至interlocked系列函數等多種手段。但是在日常的編程中,我們使用這些手段對 “多個線程同時對同一個資源進行讀寫”的時候,在讀寫之前先要對資源假鎖,讀寫完之後要對資源解鎖。

設想這樣一種情況,有一個ftp伺服器,每天有很頻繁的對這個ftp服務的檔案進行下載,但是幾乎好幾天才會對這些檔案進行更新。在我們每一次對檔案下載的時候,讀取檔案的時候都要對檔案進行加鎖,以保證同時沒有其他人對檔案進行寫入。但是這些加鎖的行為,在99%的時候都是不會有人同時寫入檔案的,只有1%的情況下會有人同時也要寫入檔案。這樣的話,我們多鎖就大大的浪費了,而且你在加鎖的同時,別人即使也只是讀取檔案,也需要等你先解鎖。


解決這個問題的辦法是,對檔案的讀取設定共用鎖定,多個線程可以同時讀檔案,不會互相阻塞。再設定獨佔鎖,當要對檔案進行寫入的時候,加上獨佔鎖,這樣別的線程此時不能讀也不能寫。


windows提供了一個稱為slim 的共用/獨佔鎖來解決這個問題。但是呢,slim只在vista和window server 2008才支援。在之前的版本上沒有支援。於是,我就w利用現有的線程同步手段,來類比達到slim這一個共用/獨佔鎖的功能,代碼封裝如下:



</pre><pre name="code" class="cpp">//共用和獨佔鎖(讀不鎖,寫鎖),適用於資源的讀的頻率比寫的頻率高的情況//共用鎖定: 大家都可以同時讀,但是不能寫。//獨佔鎖: 就是只有一個人獨佔使用,不管是讀還是寫//規定:acquire和release必須成對出現,不支援嵌套以及互相嵌套//缺點:需要對加鎖過程本身進行臨界區控制,會帶來細微的效能損失#ifdef __cplusplusextern "C" {#endifstruct SELock //Shared & Exclusive lock{       RTL_CRITICAL_SECTION sec_shared,sec_exclusive; //對加鎖代碼本身進行臨界區控制    HANDLE exclusive_evt;    HANDLE shared_evt;    volatile long shared_count;};//初始化一個SE鎖_inline void InitializeSELock(SELock *lock){    InitializeCriticalSection(&lock->sec_shared);    InitializeCriticalSection(&lock->sec_exclusive);    lock->exclusive_evt = CreateEventW(NULL,TRUE,TRUE,NULL);    lock->shared_evt = CreateEventW(NULL,TRUE,TRUE,NULL);    lock->shared_count = 0;}//清理一個SE鎖_inline void DeleteSELock(SELock *lock){        DeleteCriticalSection(&lock->sec_shared);    DeleteCriticalSection(&lock->sec_exclusive);    CloseHandle(lock->exclusive_evt);    CloseHandle(lock->shared_evt);    lock->shared_count = 0;}//請求共用鎖定,用於讀_inline void AcquireSELockShared(SELock *lock){    EnterCriticalSection(&lock->sec_exclusive);       EnterCriticalSection(&lock->sec_shared);         WaitForSingleObject(lock->exclusive_evt,INFINITE); //等待獨佔鎖        ++lock->shared_count;    if(lock->shared_count)        ResetEvent(lock->shared_evt); //開啟共用鎖定          LeaveCriticalSection(&lock->sec_shared);    LeaveCriticalSection(&lock->sec_exclusive);}//釋放共用鎖定_inline void ReleaseSELockShared(SELock *lock){    EnterCriticalSection(&lock->sec_shared);        --lock->shared_count;        if(!lock->shared_count)        SetEvent(lock->shared_evt); //關閉共用鎖定            LeaveCriticalSection(&lock->sec_shared);    }//請求獨佔鎖_inline void AcquireSELockExclusive(SELock *lock){    EnterCriticalSection(&lock->sec_exclusive);        WaitForSingleObject(lock->exclusive_evt,INFINITE); //等待獨佔鎖    WaitForSingleObject(lock->shared_evt,INFINITE); //等待共用鎖定    ResetEvent(lock->exclusive_evt); //開啟獨佔鎖    LeaveCriticalSection(&lock->sec_exclusive);}//釋放獨佔鎖_inline void ReleaseSELockExclusive(SELock *lock){    SetEvent(lock->exclusive_evt); //關閉獨佔鎖}#ifdef __cplusplus}#endif


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.