#pragma once
#include<mutex>
#include <condition_variable>
class ReadWriteLock
{
public:
ReadWriteLock(void);
~ReadWriteLock(void);
void LockRead(void);
void LockWrite(void);
std::mutex m_lock_writeCount;
std::mutex m_lock_preWriteCount;
std::mutex m_lock_readCount;
int m_readCount;
int m_writeCount;
int m_preWriteCount;
std::condition_variable m_cv;
std::condition_variable m_cvPreWrite;
void UnlockRead(void);
void UnlockWrite(void);
};
#include "stdafx.h"
#include "ReadWriteLock.h"
ReadWriteLock::ReadWriteLock(void)
: m_readCount(0), m_writeCount(0)
{
}
ReadWriteLock::~ReadWriteLock(void)
{
}
/*
*張氏讀寫鎖 2019,[email protected] Beijing Normal University
*解決了多線程置換hashmap等操作中,需要線程同步控制的問題
*使用請保留作者信息,以保證程序的正確性
*/
void ReadWriteLock::LockRead(void)
{
Loop:
m_lock_preWriteCount.lock();//鎖preWriteCount
m_lock_writeCount.lock();//鎖writeCount
m_lock_readCount.lock();//鎖readCount
if(m_preWriteCount>0||m_writeCount>0){//放入唯一一個讀進程進入預寫與寫判斷的網關
m_lock_preWriteCount.unlock();
m_lock_writeCount.unlock();
m_lock_readCount.unlock();
//這裏可以考慮加入-1信號量2操作(信號量2控制preWriteCount和writeCount)
goto Loop;
}else{//沒有寫操作也沒有預寫操作,則允許放入讀的進程
++m_readCount;//讀進程加1
m_lock_preWriteCount.unlock();
m_lock_writeCount.unlock();
m_lock_readCount.unlock();
}
}
void ReadWriteLock::UnlockRead(void)
{
m_lock_readCount.lock();//完成讀,則讀進程數減一
--m_readCount;
//這裏可以考慮加入+1信號量1操作(信號量1控制writeCount和readCount)
m_lock_readCount.unlock();
}
void ReadWriteLock::LockWrite(void)
{
m_lock_preWriteCount.lock();
++m_preWriteCount;
m_lock_preWriteCount.unlock();//預寫進程加1
Loop:
m_lock_writeCount.lock();
m_lock_readCount.lock();
if(m_writeCount>0||m_readCount>0){//等待所有已進入預寫與寫網關的讀進程結束,等待寫進程結束
m_lock_writeCount.unlock();
m_lock_readCount.unlock();
//這裏可以考慮加入-1信號量1操作
goto Loop;
}else{//進入寫進程
m_writeCount=1;//禁止其他寫進程和其他讀進程進入
m_lock_writeCount.unlock();
m_lock_readCount.unlock();
}
//放開預寫判斷鎖
m_lock_preWriteCount.lock();//預寫進程減一
--m_preWriteCount;
//這裏可以考慮加入+1信號量2操作
m_lock_preWriteCount.unlock();
}
void ReadWriteLock::UnlockWrite(void)
{
m_lock_writeCount.lock();//寫進程置爲0,放入預寫進程或讀進程
m_writeCount=0;
//這裏可以考慮加入+1信號量1操作
//這裏可以考慮加入+1信號量2操作
m_lock_writeCount.unlock();
}
加入信號量後,可以完美實現低CPU消耗的ReadWriteLock。