Windows线程同步【4】读写锁(RWMutex)

在视频播放机程序中,经常采用这样的架构:

一个负责读文件的线程,负责从媒体文件中读取数据并将数据包放入一个包队列(queue),另外有多个线程从这个包队列中取包并解码,然后交给负责显示的线程以便显示图像。于是,便形成了多个线程共享一个队列,一个写,多个只读不写的情形。

在很多时候,我们都会遇到一个写线程(负责写数据),多个读线程(负责读数据)的情形。在这类情形下,当然可以用锁来保证每个线程对共享数据的访问是独占的。但这样的做法在此情形下是低效的,因为它会使得一个读线程在读数据时另外的读线程只能干等着。

考虑到一个线程的对共享数据的读不妨碍其他线程的读,我们需要“读写锁”这个东西。

设m为一个读写锁,那么,当线程A对m上了写锁时,其他线程便不能对m上读锁或写锁,直到A解开m的写锁;当一个线程B对m上了读锁时,其他线程可以对m上读锁,不能对m上写锁,直到B对m解开读锁。


一、初始化

使用读写锁之前,要定义一个SRWLOCK类型的变量:

SRWLOCK rwm;

和临界区一样,rwm不能在代码中修改读取,对它的所有操作必须通过相关的函数来进行

用InitializeSRWLock函数初始化读写锁,

InitializeSRWLock(&rwm);


二、上锁与解锁

// 上读锁
AcquireSRWLockShared(&rwm);

// 解读锁
ReleaseSRWLockShared(&rwm);

// 上写锁
AcquireSRWLockExclusive(&rwm);

// 解写锁
ReleaseSRWLockExclusive(&rwm);


三、销毁

读写锁不需要手动销毁。


四、封装成类

为了使用方便,我一般将其封装成一个类,以达到“开箱即用”的效果。

头文件:

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_);
}

你可能感兴趣的:(windows,线程,同步,读写锁)