谁给个读写锁的思路?可以多个读只能一个写。

ATMCash4423 2016-01-12 05:52:02
谁给个读写锁的思路?可以多个读只能一个写。
SRWLock只能在VS2010上用,所以只能自己写一个了。。
...全文
473 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
jaye8090 2017-06-06
  • 打赏
  • 举报
回复
引用 4 楼 pcboyxhy 的回复:
一把读锁r,一把写锁w,计数器b,读的时候 r.lock() ++b If b == 1, w.lock() r.unlock() 读完了解锁 r.lock() --b If b == 0, w.unlock() r.unlock() writer就简单多了 w.lock() //写入... w.unlock() RWLocker要注意饥饿问题
简单易懂,赞
shenyi0106 2016-01-13
  • 打赏
  • 举报
回复
引用 6 楼 ATMCash4423 的回复:
[quote=引用 5 楼 shenyi0106 的回复:]

// 读写锁
class RWMutex
{
public:
	inline RWMutex()
	{
		 m_nWaitingReaders = m_nWaitingWriters = m_nActive = 0;
		 m_readSemaphore.Create(MAXLONG);
		 m_writeSemaphore.Create(MAXLONG);

	}

	inline virtual ~RWMutex()
	{
#ifdef _DEBUG
		// A SWMRG shouldn't be destroyed if any threads are using the resource
		if (m_nActive != 0)
		{
			DebugBreak();
		}
#endif
		m_nWaitingReaders = m_nWaitingWriters = m_nActive = 0;
		m_readSemaphore.Close();
		m_writeSemaphore.Close();
	}

	inline void ReadLock(void)
	{
		m_mutex.Lock();
		// Are there writers waiting or is a writer writing?
		BOOL fResourceWritePending = (m_nWaitingWriters || (m_nActive < 0));
		if(fResourceWritePending)
		{ 
			// This reader must wait, increment the count of waiting readers
			m_nWaitingReaders++;
		} 
		else
		{
			// This reader can read, increment the count of active readers
			m_nActive++;
		}
		m_mutex.Unlock();

		if (fResourceWritePending)
		{ 
			// This thread must wait
			m_readSemaphore.Wait(INFINITE);
		}
	}

	inline void WriteLock(void)
	{
		// Ensure exclusive access to the member variables
		m_mutex.Lock();
		// Are there any threads accessing the resource?
		BOOL fResourceOwned = (m_nActive != 0);
		if (fResourceOwned)
		{
			// This writer must wait, increment the count of waiting writers
			m_nWaitingWriters++;
		}
		else
		{ 
			// This writer can write, decrement the count of active writers
			m_nActive = -1;
		}
		m_mutex.Unlock();

		if (fResourceOwned)
		{ 
			// This thread must wait
			m_writeSemaphore.Wait(INFINITE);
		}
	}
	
	inline void Unlock()
	{
		// Ensure exclusive access to the member variables
		m_mutex.Lock();

		if (m_nActive > 0)
		{
			// Readers have control so a reader must be done
			m_nActive--;
		} 
		else
		{ 
			// Writers have control so a writer must be done
			m_nActive++;
		} 

		// Assume no threads are waiting
		Semaphore *pSemaphore = NULL;  
		// Assume only 1 waiter wakes; always true for writers
		LONG lCount = 1;

		if (m_nActive == 0)
		{
			// No thread has access, who should wake up?
			// NOTE: It is possible that readers could never get access
			//       if there are always writers wanting to write 
			if (m_nWaitingWriters > 0)
			{
				// Writers are waiting and they take priority over readers
				// A writer will get access
				m_nActive = -1;
				// Writers wait on this semaphore
				pSemaphore = &m_writeSemaphore;
				// One less writer will be waiting
				m_nWaitingWriters--;
				// NOTE: The semaphore will release only 1 writer thread 
			} 
			else if (m_nWaitingReaders > 0)
			{
				// Readers are waiting and no writers are waiting
				// All readers will get access
				m_nActive = m_nWaitingReaders;
				// No readers will be waiting
				m_nWaitingReaders = 0;
				// Readers wait on this semaphore
				pSemaphore = &m_readSemaphore;
				// Semaphore releases all readers
				lCount = m_nActive;              
			} 
			else
			{
				// There are no threads waiting at all; no semaphore gets released
			}
		} 
		// Allow other threads to attempt reading/writing
		m_mutex.Unlock();

		if (pSemaphore != NULL)
		{ 
			// Some threads are to be released
			pSemaphore->Release(lCount);
		}
	}

private:
	CriticalSection  m_mutex;
	Semaphore        m_readSemaphore, m_writeSemaphore;
	int              m_nWaitingReaders, m_nWaitingWriters, m_nActive;
};
windows核心编程中的例子
请问是《windows核心编程第五版》吗?我看了几遍都没看到这个例子,您是在哪个章节看到的啊? Semaphore 是什么类?[/quote] 线程同步章节,具体哪个章节,哪个版本我记不清楚了。 另外,源码是我修改后的,CriticalSection和Semaphore是对临界区和信号量的封装,你可以换成API就可以了
ATMCash4423 2016-01-13
  • 打赏
  • 举报
回复
引用 5 楼 shenyi0106 的回复:

// 读写锁
class RWMutex
{
public:
	inline RWMutex()
	{
		 m_nWaitingReaders = m_nWaitingWriters = m_nActive = 0;
		 m_readSemaphore.Create(MAXLONG);
		 m_writeSemaphore.Create(MAXLONG);

	}

	inline virtual ~RWMutex()
	{
#ifdef _DEBUG
		// A SWMRG shouldn't be destroyed if any threads are using the resource
		if (m_nActive != 0)
		{
			DebugBreak();
		}
#endif
		m_nWaitingReaders = m_nWaitingWriters = m_nActive = 0;
		m_readSemaphore.Close();
		m_writeSemaphore.Close();
	}

	inline void ReadLock(void)
	{
		m_mutex.Lock();
		// Are there writers waiting or is a writer writing?
		BOOL fResourceWritePending = (m_nWaitingWriters || (m_nActive < 0));
		if(fResourceWritePending)
		{ 
			// This reader must wait, increment the count of waiting readers
			m_nWaitingReaders++;
		} 
		else
		{
			// This reader can read, increment the count of active readers
			m_nActive++;
		}
		m_mutex.Unlock();

		if (fResourceWritePending)
		{ 
			// This thread must wait
			m_readSemaphore.Wait(INFINITE);
		}
	}

	inline void WriteLock(void)
	{
		// Ensure exclusive access to the member variables
		m_mutex.Lock();
		// Are there any threads accessing the resource?
		BOOL fResourceOwned = (m_nActive != 0);
		if (fResourceOwned)
		{
			// This writer must wait, increment the count of waiting writers
			m_nWaitingWriters++;
		}
		else
		{ 
			// This writer can write, decrement the count of active writers
			m_nActive = -1;
		}
		m_mutex.Unlock();

		if (fResourceOwned)
		{ 
			// This thread must wait
			m_writeSemaphore.Wait(INFINITE);
		}
	}
	
	inline void Unlock()
	{
		// Ensure exclusive access to the member variables
		m_mutex.Lock();

		if (m_nActive > 0)
		{
			// Readers have control so a reader must be done
			m_nActive--;
		} 
		else
		{ 
			// Writers have control so a writer must be done
			m_nActive++;
		} 

		// Assume no threads are waiting
		Semaphore *pSemaphore = NULL;  
		// Assume only 1 waiter wakes; always true for writers
		LONG lCount = 1;

		if (m_nActive == 0)
		{
			// No thread has access, who should wake up?
			// NOTE: It is possible that readers could never get access
			//       if there are always writers wanting to write 
			if (m_nWaitingWriters > 0)
			{
				// Writers are waiting and they take priority over readers
				// A writer will get access
				m_nActive = -1;
				// Writers wait on this semaphore
				pSemaphore = &m_writeSemaphore;
				// One less writer will be waiting
				m_nWaitingWriters--;
				// NOTE: The semaphore will release only 1 writer thread 
			} 
			else if (m_nWaitingReaders > 0)
			{
				// Readers are waiting and no writers are waiting
				// All readers will get access
				m_nActive = m_nWaitingReaders;
				// No readers will be waiting
				m_nWaitingReaders = 0;
				// Readers wait on this semaphore
				pSemaphore = &m_readSemaphore;
				// Semaphore releases all readers
				lCount = m_nActive;              
			} 
			else
			{
				// There are no threads waiting at all; no semaphore gets released
			}
		} 
		// Allow other threads to attempt reading/writing
		m_mutex.Unlock();

		if (pSemaphore != NULL)
		{ 
			// Some threads are to be released
			pSemaphore->Release(lCount);
		}
	}

private:
	CriticalSection  m_mutex;
	Semaphore        m_readSemaphore, m_writeSemaphore;
	int              m_nWaitingReaders, m_nWaitingWriters, m_nActive;
};
windows核心编程中的例子
请问是《windows核心编程第五版》吗?我看了几遍都没看到这个例子,您是在哪个章节看到的啊? Semaphore 是什么类?
ATMCash4423 2016-01-13
  • 打赏
  • 举报
回复
引用 4 楼 pcboyxhy 的回复:
一把读锁r,一把写锁w,计数器b,读的时候 r.lock() ++b If b == 1, w.lock() r.unlock() 读完了解锁 r.lock() --b If b == 0, w.unlock() r.unlock() writer就简单多了 w.lock() //写入... w.unlock() RWLocker要注意饥饿问题
谢谢!看来还是需要用到读计数啊,我也想过用WaitForMultipleObjects,每读一次创建一个handle,貌似我这样效率更低,还不如计数。。。
shenyi0106 2016-01-13
  • 打赏
  • 举报
回复

// 读写锁
class RWMutex
{
public:
	inline RWMutex()
	{
		 m_nWaitingReaders = m_nWaitingWriters = m_nActive = 0;
		 m_readSemaphore.Create(MAXLONG);
		 m_writeSemaphore.Create(MAXLONG);

	}

	inline virtual ~RWMutex()
	{
#ifdef _DEBUG
		// A SWMRG shouldn't be destroyed if any threads are using the resource
		if (m_nActive != 0)
		{
			DebugBreak();
		}
#endif
		m_nWaitingReaders = m_nWaitingWriters = m_nActive = 0;
		m_readSemaphore.Close();
		m_writeSemaphore.Close();
	}

	inline void ReadLock(void)
	{
		m_mutex.Lock();
		// Are there writers waiting or is a writer writing?
		BOOL fResourceWritePending = (m_nWaitingWriters || (m_nActive < 0));
		if(fResourceWritePending)
		{ 
			// This reader must wait, increment the count of waiting readers
			m_nWaitingReaders++;
		} 
		else
		{
			// This reader can read, increment the count of active readers
			m_nActive++;
		}
		m_mutex.Unlock();

		if (fResourceWritePending)
		{ 
			// This thread must wait
			m_readSemaphore.Wait(INFINITE);
		}
	}

	inline void WriteLock(void)
	{
		// Ensure exclusive access to the member variables
		m_mutex.Lock();
		// Are there any threads accessing the resource?
		BOOL fResourceOwned = (m_nActive != 0);
		if (fResourceOwned)
		{
			// This writer must wait, increment the count of waiting writers
			m_nWaitingWriters++;
		}
		else
		{ 
			// This writer can write, decrement the count of active writers
			m_nActive = -1;
		}
		m_mutex.Unlock();

		if (fResourceOwned)
		{ 
			// This thread must wait
			m_writeSemaphore.Wait(INFINITE);
		}
	}
	
	inline void Unlock()
	{
		// Ensure exclusive access to the member variables
		m_mutex.Lock();

		if (m_nActive > 0)
		{
			// Readers have control so a reader must be done
			m_nActive--;
		} 
		else
		{ 
			// Writers have control so a writer must be done
			m_nActive++;
		} 

		// Assume no threads are waiting
		Semaphore *pSemaphore = NULL;  
		// Assume only 1 waiter wakes; always true for writers
		LONG lCount = 1;

		if (m_nActive == 0)
		{
			// No thread has access, who should wake up?
			// NOTE: It is possible that readers could never get access
			//       if there are always writers wanting to write 
			if (m_nWaitingWriters > 0)
			{
				// Writers are waiting and they take priority over readers
				// A writer will get access
				m_nActive = -1;
				// Writers wait on this semaphore
				pSemaphore = &m_writeSemaphore;
				// One less writer will be waiting
				m_nWaitingWriters--;
				// NOTE: The semaphore will release only 1 writer thread 
			} 
			else if (m_nWaitingReaders > 0)
			{
				// Readers are waiting and no writers are waiting
				// All readers will get access
				m_nActive = m_nWaitingReaders;
				// No readers will be waiting
				m_nWaitingReaders = 0;
				// Readers wait on this semaphore
				pSemaphore = &m_readSemaphore;
				// Semaphore releases all readers
				lCount = m_nActive;              
			} 
			else
			{
				// There are no threads waiting at all; no semaphore gets released
			}
		} 
		// Allow other threads to attempt reading/writing
		m_mutex.Unlock();

		if (pSemaphore != NULL)
		{ 
			// Some threads are to be released
			pSemaphore->Release(lCount);
		}
	}

private:
	CriticalSection  m_mutex;
	Semaphore        m_readSemaphore, m_writeSemaphore;
	int              m_nWaitingReaders, m_nWaitingWriters, m_nActive;
};
windows核心编程中的例子
pcboyxhy 2016-01-12
  • 打赏
  • 举报
回复
一把读锁r,一把写锁w,计数器b,读的时候 r.lock() ++b If b == 1, w.lock() r.unlock() 读完了解锁 r.lock() --b If b == 0, w.unlock() r.unlock() writer就简单多了 w.lock() //写入... w.unlock() RWLocker要注意饥饿问题
pcboyxhy 2016-01-12
  • 打赏
  • 举报
回复
用两把互斥锁+一个reader计数器就可以了
bluesen 2016-01-12
  • 打赏
  • 举报
回复
用条件变量。但也xp下也不支持
gz_qmc 2016-01-12
  • 打赏
  • 举报
回复
线程代权柄 传参时候授权即可

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧