一种跨平台的快速锁

    

    C++11发布了四种不同的用于跨平台的锁,但其为了夸平台做了很多工作,在需要性能要求的情况下,大量的调用枷锁解锁必定会导致效率问题(现在计算机都这么快了这点运算其实又算得了什么呢,以后就不拿性能当幌子了闭嘴),实际上在C++11发布之前就写好了一个夸平台的锁(大部分平台都可以用),代码比较简洁可以直接拿来用,自己平时用的比较多,真正原因就是自己不舍得这些代码用C++11的代替了。


    这里要介绍的锁在同线程下支持递归枷锁,windows下使用临界区,不涉及内核对象,其他平台使用pthread库中的pthread_mutex_t对象,含有PTHREAD_MUTEX_RECURSIVE属性实现归枷锁,代码分了两个文件来实现,分别粘贴在下面,其中#include "PLTConfig.h"文件中定义了一些系统宏,参考QT定义的系统宏。


这是.h文件


/* 
============================================================================================
	Locker 快速锁对象
	同线程内可以递归加锁
	加锁和解锁必须在同一线程内
	这种锁是进程内私有 不能和其他进程公用
	windows下使用临界区 pthread下使用PTHREAD_MUTEX_RECURSIVE属性的互斥量

	add 2013.11.22 by yuwf

	Copyright (c), ...	

=============================================================================================
*/

#ifndef _PALANTIR_LOCKER_H
#define _PALANTIR_LOCKER_H

#include "PLTConfig.h"	// 根据系统定义 PLT_OS_WIN 和 PTHREAD 宏

#if defined(PLT_OS_WIN)
#include <windows.h>
#elif defined(PTHREAD)
#include <pthread.h>
#endif

namespace Palantir
{
	// 允许加锁线程递归加锁
	class Locker
	{
	public:
		Locker();
		~Locker();

		// 加锁 不是同一线程枷锁会阻塞
		void Lock();

		// 非阻塞 枷锁成功返回true 否则返回false
		bool TryLock();

		// 解锁
		void Unlock();

	protected:
#if defined(PLT_OS_WIN)
		CRITICAL_SECTION	m_critical_section;	// 临界区
#elif defined(PTHREAD)
		pthread_mutex_t 	m_mutex;			// 互斥锁
#endif

	private:
		// 禁止拷贝和赋值构造
		Locker( const Locker& ) {};
		Locker& operator = ( const Locker& ) { return *this; };
	};

	// 空锁 辅助使用
	class EmptyLocker
	{
	public:
		// 加锁
		void Lock() {};

		bool TryLock() { return true; };

		// 解锁
		void Unlock() {};
	};
	
	// 加锁辅助工具
	template<class _LockerType_>
	class LockerGuard
	{
	public:
		LockerGuard( _LockerType_& locker ) 
			: m_locker(locker)
		{
			locker.Lock();
		}
		~LockerGuard()
		{
			m_locker.Unlock();
		}
	protected:
		_LockerType_& m_locker;
	};

	typedef LockerGuard<Locker> AutoLocker;
	
}

#endif



这是.cpp文件

/* 
============================================================================================
	Locker 快速锁对象 实现文件

	add 2013.11.22 by yuwf

	Copyright (c), ...	

=============================================================================================
*/


#include "PLTLocker.h"

namespace Palantir
{
	Locker::Locker()
	{
#if defined(PLT_OS_WIN)
		InitializeCriticalSection( &m_critical_section );
#elif defined(PTHREAD)
		pthread_mutexattr_t attr;
		pthread_mutexattr_init( &attr );
		pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE );	// 这个互斥锁可递归加锁 因为windows下的临界区可以递归加锁
		pthread_mutex_init( &m_mutex, &attr );
#endif
	}

	Locker::~Locker()
	{
#if defined(PLT_OS_WIN)
		DeleteCriticalSection( &m_critical_section );
#elif defined(PTHREAD)
		pthread_mutex_destroy( &m_mutex );
#endif
	}

	void Locker::Lock()
	{
#if defined(PLT_OS_WIN)
		EnterCriticalSection( &m_critical_section );
#elif defined(PTHREAD)
		pthread_mutex_lock( &m_mutex );
#endif
	}

	bool Locker::TryLock()
	{
#if defined(PLT_OS_WIN)
		if ( !TryEnterCriticalSection( &m_critical_section ) )
		{
			return false;
		}
#elif defined(PTHREAD)
		if( pthread_mutex_trylock( &m_mutex ) != 0 )
		{
			return false;
		}
#endif
		return true;
	}

	void Locker::Unlock()
	{
#if defined(PLT_OS_WIN)
		LeaveCriticalSection( &m_critical_section );
#elif defined(PTHREAD)
		pthread_mutex_unlock( &m_mutex );
#endif
	}
}



代码中定义了一个空锁EmptyLocker,主要用来辅助使用,比如在后面要介绍的内存池中可以传入一个空锁来实现一个不需要枷锁的内存池,LockerGuard也是用来辅助使用,功能很简单,不做赘述。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值