C++多线程同步之临界区(CriticalSection)、WINDOWS和LINUX

匿名 (未验证) 提交于 2019-12-02 21:53:52

一、Win32平台

1、相关头文件和接口

#include <windows.h>  CRITICAL_SECTION cs;//定义临界区对象 InitializeCriticalSection(&cs);//初始化临界区 EnterCriticalSection(&cs);//进入临界区 LeaveCriticalSection(&cs);//离开临界区 DeleteCriticalSection(&cs);//删除临界区
//线程同步类。是对Win32临界区对象的封装。 	class CMyCriticalSection 	{ 	public: 		//CCriticalSection类的构造函数,初始化临界区,析构函数删除临界区。 		CMyCriticalSection()	{ ::InitializeCriticalSection(&m_crit); } 		~CMyCriticalSection() { ::DeleteCriticalSection(&m_crit); } 		//进人临界区 		void Enter() { ::EnterCriticalSection(&m_crit); } 		//离开临界区 		void Leave() { ::LeaveCriticalSection(&m_crit); }  	private: 		//内部线程互斥对象 		CRITICAL_SECTION m_crit; 	}; 	typedef CMyCriticalSection CMylock;   	//临界区锁类。构造函数加锁,析构函数解锁。 	class CMyGuard 	{ 	public: 		CMyGuard(CMylock &crit) : m_crit(crit) { m_crit.Enter(); } 		~CMyGuard() { m_crit.Leave(); } 	private: 		//内部正真的线程互斥对象的引用。 		CMylock & m_crit; 	};

 

 

代码 工作例子:

	class aaa{      private:  		CMylock m_lock;  	  	};   VOID BBB () {  		CMyGuard l(m_lock);   }

2.Linuxƽ̨

在Linux环境下,没有Windows下的临界区的概念,但是也可以利用互斥量实现该功能。Linux下的API如下,在前面的博文里也有讲到过,可以参考http://blog.csdn.net/olansefengye1/article/details/53086141。

include <pthread.h> int pthread_mutexattr_init(pthread_mutexattr_t *attr); /*初始化函数*/ int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);/*去初始化函数*/  int pthread_mutex_lock(pthread_mutexattr_t *attr)/*加锁*/ int pthread_mutex_unlock(pthread_mutexattr_t *attr)/*解锁*/123456

但是两者并不是完全一样的,他们的区别总结如下: 
1、临界区只能用于对象在同一进程里线程间的互斥访问;互斥体可以用于对象进程间或线程间的互斥访问。 
2、临界区是非内核对象,只在用户态进行锁操作,速度快;互斥体是内核对象,在核心态进行锁操作,速度慢。 
3、临界区和互斥体在Windows平台都下可用;Linux下只有互斥体可用。 
4、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。 
5、互斥量:为协调共同对一个共享资源的单独访问而设计的。
 

3. 总结类

#ifndef BASIC_MYLOCK_H #define BASIC_MYLOCK_H  #ifdef _MSC_VER  	#include <WinSock2.h> // 在每个windows.h 的include 前加 防止AF_IPX 重定义 	#include "Windows.h" 	//系统用的线程互斥锁。 namespace ITapManager { 	//线程同步类。是对Win32临界区对象的封装。 	class CMyCriticalSection 	{ 	public: 		//CCriticalSection类的构造函数,初始化临界区,析构函数删除临界区。 		CMyCriticalSection()	{ ::InitializeCriticalSection(&m_crit); } 		~CMyCriticalSection() { ::DeleteCriticalSection(&m_crit); } 		//进人临界区 		void Enter() { ::EnterCriticalSection(&m_crit); } 		//离开临界区 		void Leave() { ::LeaveCriticalSection(&m_crit); }  	private: 		//内部线程互斥对象 		CRITICAL_SECTION m_crit; 	}; 	typedef CMyCriticalSection CMylock;   	//临界区锁类。构造函数加锁,析构函数解锁。 	class CMyGuard 	{ 	public: 		CMyGuard(CMylock &crit) : m_crit(crit) { m_crit.Enter(); } 		~CMyGuard() { m_crit.Leave(); } 	private: 		//内部正真的线程互斥对象的引用。 		CMylock & m_crit; 	}; } #endif // _MSC_VER #ifdef __GNUC__   #include <pthread.h> namespace ITapManager { 	class CMyCriticalSection 	{ 	public: 		//CCriticalSection类的构造函数,初始化临界区,析构函数删除临界区。 		CMyCriticalSection() 		{  			::pthread_mutex_init( &m_mutex, NULL);	//普通锁 		}	 		 		~CMyCriticalSection() 		{  			::pthread_mutex_destroy( &m_mutex);	 		} 		 		//进人临界区 		void Enter() const 		{  			::pthread_mutex_lock( &m_mutex);	 		} 		 		//离开临界区 		void Leave() 		{  			::pthread_mutex_unlock( &m_mutex);	 		}  	private: 		//内部线程互斥对象 		mutable pthread_mutex_t m_mutex;	 	};  	typedef CMyCriticalSection CMylock;   	//临界区锁类。构造函数加锁,析构函数解锁。 	class CMyGuard 	{ 	public: 		CMyGuard(CMylock &crit) : m_crit(crit) { m_crit.Enter(); } 		~CMyGuard() { m_crit.Leave(); } 	private: 		//内部正真的线程互斥对象的引用。 		CMylock & m_crit;  	}; } #endif // __GNUC__          #endif // BASIC_MYLOCK_H

 

文章来源: https://blog.csdn.net/baidu_39486224/article/details/86549536
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!