⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mutex.cpp

📁 LINUX下很好的C++线程池源码类
💻 CPP
字号:
#include "mutex.h"

#include <stdlib.h>

#include <string.h>



#ifndef WIN32

	static pthread_mutexattr_t  *sMutexAttr=NULL;

	static void MutexAttrInit();

	static pthread_once_t sMutexAttrInit = PTHREAD_ONCE_INIT;

#endif



MMutex::MMutex()

{

#ifdef WIN32

    ::InitializeCriticalSection(&fMutex);

#else

    (void)pthread_once(&sMutexAttrInit, MutexAttrInit);

    (void)pthread_mutex_init(&fMutex, sMutexAttr);

#endif

}



#ifndef WIN32

void MutexAttrInit()

{

    sMutexAttr = (pthread_mutexattr_t*)malloc(sizeof(pthread_mutexattr_t));

    memset(sMutexAttr, 0, sizeof(pthread_mutexattr_t));

    pthread_mutexattr_init(sMutexAttr);

}

#endif



MMutex::~MMutex()

{

#ifdef WIN32

    ::DeleteCriticalSection(&fMutex);

#else

    pthread_mutex_destroy(&fMutex);

#endif

}



#ifdef WIN32

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////



//---------------------------------------------------------------------

// MRWMutex - constructs a read-write lock object and events

//

// Exceptions   : NONE

// Return Codes : NONE 

//---------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////

MRWMutex::MRWMutex() : m_nLockCount(0), m_nWaitingReaders(0), m_nWaitingWriters(0)

///////////////////////////////////////////////////////////////////////

{

}



//---------------------------------------------------------------------

// ~MRWMutex - destroys the read-write lock object and events

//

// Exceptions   : NONE

// Return Codes : NONE 

//---------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////

MRWMutex::~MRWMutex()

///////////////////////////////////////////////////////////////////////

{

	// Make sure mutex is unlocked when object is destroyed

	m_mtxLockCount.Unlock();

}



//---------------------------------------------------------------------

// LockRead - allows multiple reading threads to lock a resource

// for shared access

//

// Exceptions   : NONE

// Return Codes : true (success), false (failure)

//---------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////

void MRWMutex::LockRead()

///////////////////////////////////////////////////////////////////////

{

	WaitingReaders();



	if (m_nLockCount < 0)

	{

		// a reader thread must wait for the read event.. if a writer is holding lock

		m_semReader.Wait();

	}



	IncrementReaders();

}



//---------------------------------------------------------------------

// UnLockRead - allows reader threads to unlock a resource

//

// Exceptions   : NONE

// Return Codes : true (success), false (failure)

//---------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////

void MRWMutex::UnlockRead()

///////////////////////////////////////////////////////////////////////

{

	DecrementReaders();



	if (!m_nWaitingReaders && !m_nLockCount)

	{

		m_semWriter.Signal();

	}

}



//---------------------------------------------------------------------

// LockWrite - allows single writer thread to lock a resource

// for exclusive access

//

// Exceptions   : NONE

// Return Codes : true (success), false (failure)

//---------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////

void MRWMutex::LockWrite()

///////////////////////////////////////////////////////////////////////

{

	WaitingWriters();



	while (m_nLockCount)

	{

		m_semWriter.Wait();

	}



	IncrementWriters();

}



//---------------------------------------------------------------------

// UnlockWrite - allows single writing thread to unlock a resource

//

// Exceptions   : NONE

// Return Codes : true (success), false (failure)

//---------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////

void MRWMutex::UnlockWrite()

///////////////////////////////////////////////////////////////////////

{

	DecrementWriters();



	// Readers are preferred in the following section....

	if (m_nWaitingWriters && !m_nWaitingReaders)

	{

		// when no readers are waiting... signal writers, if any

		m_semWriter.Signal();

	}

	else

	{

		while (m_nWaitingReaders > 0)

		{

			m_semReader.Signal();

		}

	}

}





//---------------------------------------------------------------------

// WaitingReader() - increments waiting reader count

//

// Exceptions   : NONE

// Return Codes : true (success), false (failure)

//---------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////

int MRWMutex::WaitingReaders()

///////////////////////////////////////////////////////////////////////

{

	m_mtxLockCount.Lock();



	// One more thread is waiting on read event

	m_nWaitingReaders++;



	m_mtxLockCount.Unlock();



	return true;

}



//---------------------------------------------------------------------

// IncrementReaders() - decrements waiting reader count and increments

// lock count

//

// Exceptions   : NONE

// Return Codes : true (success), false (failure)

//---------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////

int MRWMutex::IncrementReaders()

///////////////////////////////////////////////////////////////////////

{

	// InterlockedIncrement() could also be used, instead of this mutex

	m_mtxLockCount.Lock();



	// One more thread has obtained a read lock and is no longer waiting

	if (m_nLockCount >= 0)

	{

		m_nLockCount++;

		m_nWaitingReaders--;

	}



	m_mtxLockCount.Unlock();



	return true;

}



//---------------------------------------------------------------------

// DecrementReaders() - decrements lock count

//

// Exceptions   : NONE

// Return Codes : true (success), false (failure)

//---------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////

int MRWMutex::DecrementReaders()

///////////////////////////////////////////////////////////////////////

{

	// InterlockedDecrement() could also be used, instead of this mutex

	m_mtxLockCount.Lock();



	if (m_nLockCount > 0)

	{

		// One less thread holding read lock

		m_nLockCount--;

	}



	m_mtxLockCount.Unlock();



	return true;

}



//---------------------------------------------------------------------

// WaitingWriter() - increments waiting writer count

//

// Exceptions   : NONE

// Return Codes : true (success), false (failure)

//---------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////

int MRWMutex::WaitingWriters()

///////////////////////////////////////////////////////////////////////

{

	m_mtxLockCount.Lock();



	m_nWaitingWriters++;



	m_mtxLockCount.Unlock();



	return true;

}



//---------------------------------------------------------------------

// IncrementWriters() - decrements waiting writer count and pushes

// lock count below ground level

//

// Exceptions   : NONE

// Return Codes : true (success), false (failure)

//---------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////

int MRWMutex::IncrementWriters()

///////////////////////////////////////////////////////////////////////

{

	m_mtxLockCount.Lock();



	// Only one thread can obtain a write lock .. so lock count goes underground

	// InterlockedDecrement() could also be used

	if (m_nLockCount == 0)

	{

		m_nLockCount = -1;

		m_nWaitingWriters--;

	}



	m_mtxLockCount.Unlock();



	return true;

}



//---------------------------------------------------------------------

// DecrementWriters() - pulls lock count to ground level

//

// Exceptions   : NONE

// Return Codes : true (success), false (failure)

//---------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////

int MRWMutex::DecrementWriters()

///////////////////////////////////////////////////////////////////////

{

	m_mtxLockCount.Lock();



	if (m_nLockCount == -1)

	{

		m_nLockCount = 0;

	}



	m_mtxLockCount.Unlock();



	return true;

}



//---------------------------------------------------------------------

// GetLockCount() - returns current lock count

//

// Exceptions   : NONE

// Returns      : lock count (int)

//---------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////

int MRWMutex::GetLockCount()

{

	int nCount = 0;



	m_mtxLockCount.Lock();



	nCount = m_nLockCount;



	m_mtxLockCount.Unlock();



	return nCount;

}





//---------------------------------------------------------------------

// GetWaitingReaders() - returns current no. of threads waiting for

// read access

//

// Exceptions   : NONE

// Returns      : waiting readers (int)

//---------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////

int MRWMutex::GetWaitingReaders()

{

	int nCount = 0;



	m_mtxLockCount.Lock();



	nCount = m_nWaitingReaders;



	m_mtxLockCount.Unlock();



	return nCount;

}



//---------------------------------------------------------------------

// GetWaitingWriters() - returns current no. of threads waiting for

// write access

//

// Exceptions   : NONE

// Returns      : waiting writers (int)

//---------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////

int MRWMutex::GetWaitingWriters()

{

	int nCount = 0;



	m_mtxLockCount.Lock();



	nCount = m_nWaitingWriters;



	m_mtxLockCount.Unlock();



	return nCount;

}





#else

	static pthread_rwlockattr_t  *sRWMutexAttr=NULL;

	static void RWMutexAttrInit();

	static pthread_once_t sRWMutexAttrInit = PTHREAD_ONCE_INIT;



void RWMutexAttrInit()

{

    sRWMutexAttr = (pthread_rwlockattr_t*)malloc(sizeof(pthread_rwlockattr_t));

    memset(sRWMutexAttr, 0, sizeof(pthread_rwlockattr_t));

    pthread_rwlockattr_init(sRWMutexAttr);

}



MRWMutex::MRWMutex()

{

	(void)pthread_once(&sRWMutexAttrInit, RWMutexAttrInit);

    (void)pthread_rwlock_init(&fRWMutex, sRWMutexAttr);

}



MRWMutex::~MRWMutex() 

{

	pthread_rwlock_destroy(&fRWMutex);

}



void MRWMutex::LockRead()

{

	pthread_rwlock_rdlock(&fRWMutex);

}



void MRWMutex::LockWrite()

{

	pthread_rwlock_wrlock(&fRWMutex);

}



void MRWMutex::UnlockRead()

{

	pthread_rwlock_unlock(&fRWMutex);

}



void MRWMutex::UnlockWrite()

{

	pthread_rwlock_unlock(&fRWMutex);

}



int MRWMutex::GetWaitingWriters()

{

	return 0;

}

int MRWMutex::GetWaitingReaders()

{

	return 0;

}

int MRWMutex::GetLockCount()

{

	return 0;

}



#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -