Windows線程同步【4】讀寫鎖(RWMutex)

在視頻播放機程序中,常常採用這樣的架構:架構

一個負責讀文件的線程,負責從媒體文件中讀取數據並將數據包放入一個包隊列(queue),另外有多個線程從這個包隊列中取包並解碼,而後交給負責顯示的線程以便顯示圖像。因而,便造成了多個線程共享一個隊列,一個寫,多個只讀不寫的情形。函數

在不少時候,咱們都會遇到一個寫線程(負責寫數據),多個讀線程(負責讀數據)的情形。在這類情形下,固然能夠用鎖來保證每一個線程對共享數據的訪問是獨佔的。但這樣的作法在此情形下是低效的,由於它會使得一個讀線程在讀數據時另外的讀線程只能乾等着。ui

考慮到一個線程的對共享數據的讀不妨礙其餘線程的讀,咱們須要「讀寫鎖」這個東西。spa

設m爲一個讀寫鎖,那麼,當線程A對m上了寫鎖時,其餘線程便不能對m上讀鎖或寫鎖,直到A解開m的寫鎖;當一個線程B對m上了讀鎖時,其餘線程能夠對m上讀鎖,不能對m上寫鎖,直到B對m解開讀鎖。線程


1、初始化code

使用讀寫鎖以前,要定義一個SRWLOCK類型的變量:視頻

SRWLOCK rwm;

和臨界區同樣,rwm不能在代碼中修改讀取,對它的全部操做必須經過相關的函數來進行隊列

用InitializeSRWLock函數初始化讀寫鎖,it

InitializeSRWLock(&rwm);


2、上鎖與解鎖class

// 上讀鎖
AcquireSRWLockShared(&rwm);

// 解讀鎖
ReleaseSRWLockShared(&rwm);

// 上寫鎖
AcquireSRWLockExclusive(&rwm);

// 解寫鎖
ReleaseSRWLockExclusive(&rwm);


3、銷燬

讀寫鎖不須要手動銷燬。


4、封裝成類

爲了使用方便,我通常將其封裝成一個類,以達到「開箱即用」的效果。

頭文件:

class RWMutex
{
public:
    RWMutex();
    ~RWMutex() = default;
    void RLock(); // 上讀鎖
    void RUnlock(); // 解讀鎖
    void Lock(); // 上寫鎖
    void Unlock(); // 解寫鎖

private:
    SRWLOCK Lock_;
private:
    RWMutex(const RWMutex&) = delete;
    void operator=(const RWMutex&) = delete;
};

對應的源文件:

RWMutex::RWMutex()
{
    ::InitializeSRWLock(&Lock_);
}

void RWMutex::RLock()
{
    ::AcquireSRWLockShared(&Lock_);
}

void RWMutex::RUnlock()
{
    ::ReleaseSRWLockShared(&Lock_);
}

void RWMutex::Lock()
{
    ::AcquireSRWLockExclusive(&Lock_);
}

void RWMutex::Unlock()
{
    ::ReleaseSRWLockExclusive(&Lock_);
}
相關文章
相關標籤/搜索