我需要实现三种不同类型的锁定。锁定阅读,写作和排他性。例如,有一个名为table的抽象对象,许多事务都在不同的线程中工作。
读锁是一种锁,它允许您同时读取来自不同事务的数据,但如果其中一个事务需要一个表进行写操作,则需要等到所有读锁都被删除。
写锁定允许任何事务从表中读取,但只有一个拥有该表用于写入的事务可以写入表
当只有一个事务可以访问该表时,独占锁是一个锁,而其他事件在锁被删除时等待。
我正在寻找如何使用WinApi和C / C ++实现这一点我正在尝试
class Table
{
void LockWrite()
{
if (LockLW.IsLock())
LockLW.wait_and_lock();
//
if (LockEx.IsLock())
LockEx.wait();
}
void LockExclusive()
{
{
// it is assumed that this is a thread-safe check
if (readers != 0)
FreeLockRead.wait();
}
//but there is a problem, because in this place some transactions have started to read again
if (LockLW.IsLock())
LockLW.wait_and_lock();
if (LockEx.IsLock())
LockEx.wait_and_lock();
}
void UnLockExclusive()
{
LockEx.unLock();
}
void LockRead()
{
if (LockEx.IsLock())
LockEx.wait();
//Set Lock Read
//a problem, because in this place one of transactions have got LockEx
readers += 1;
}
void UnLockRead()
{
readers -= 1;
if (readers == 0)
FreeLockRead.pulse();
}
mutex LockLW;
mutex LockEx;
event FreeLockRead;
atomic readers;
};
答案 0 :(得分:0)
在研究材料后,我找到了以下解决方案:
class Table
{
enum eFlag
{
eFree = 0,
eRead = 1,
eWrite = 2,
eExclusive = 4
};
uint32_t m_nReaders;
std::mutex m_Mutex;
uint32_t m_nFlag;
std::condition_variable m_condition;
void LockForRead()
{
std::unique_lock<std::mutex> lk(m_Mutex);
if (m_nFlag & eExclusive)
{
m_condition.wait(lk, [this]() {return !(m_nFlag & eExclusive); });
}
m_nReaders += 1;
m_nFlag |= eRead;
}
void UnLockForRead()
{
std::unique_lock<std::mutex> lk(m_Mutex);
assert(m_nReaders != 0 && (m_nFlag & eRead));
m_nReaders -= 1;
if (m_nReaders == 0)
{
m_nFlag &= ~eRead;
m_condition.notify_one();
}
}
void LockForExclusive()
{
std::unique_lock<std::mutex> lk(m_Mutex);
if (m_nFlag != eFree)
m_condition.wait(lk, [this]() {return m_nFlag == eFree; });
m_nFlag = eExclusive;
}
void UnLockForExclusive()
{
std::unique_lock<std::mutex> lk(m_Mutex);
assert(m_nFlag == eExclusive);
m_nFlag = eFree;
m_condition.notify_all();
}
void LockForWrite()
{
std::unique_lock<std::mutex> lk(m_Mutex);
if (m_nFlag & (eExclusive | eWrite))
m_condition.wait(lk, [this]() {return !(m_nFlag & (eExclusive | eWrite)); });
m_nFlag |= eWrite;
}
void UnLockForWrite()
{
std::unique_lock<std::mutex> lk(m_Mutex);
assert(m_nFlag & eWrite);
m_nFlag &= ~eWrite;
m_condition.notify_one();
}
};