700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > (转)互斥对象锁和临界区锁性能比较 .

(转)互斥对象锁和临界区锁性能比较 .

时间:2021-04-11 12:51:40

相关推荐

(转)互斥对象锁和临界区锁性能比较 .

在Win32平台上进行多线程编程,常会用到锁。下边用C++实现了互斥对象(Mutex)锁和临界区(CRITICAL_SECTION)锁,以加深理解和今后方便使用。代码已在VS环境下编译测试通过。

Lock.h

[cpp]view plaincopyprint? #ifndef_Lock_H #define_Lock_H #include<windows.h> //锁接口类 classILock{public:virtual~ILock(){}virtualvoidLock()const=0;virtualvoidUnlock()const=0;};//互斥对象锁类 classMutex:publicILock{public:Mutex();~Mutex();virtualvoidLock()const;virtualvoidUnlock()const;private:HANDLEm_mutex;};//临界区锁类 classCriSection:publicILock{public:CriSection();~CriSection();virtualvoidLock()const;virtualvoidUnlock()const;private:CRITICAL_SECTIONm_critclSection;};//锁 classCMyLock{public:CMyLock(constILock&);~CMyLock();private:constILock&m_lock;};#endif

#ifndef _Lock_H #define _Lock_H #include <windows.h> //锁接口类 class ILock { public: virtual ~ILock() {} virtual void Lock() const = 0; virtual void Unlock() const = 0; }; //互斥对象锁类 class Mutex : public ILock { public: Mutex(); ~Mutex(); virtual void Lock() const; virtual void Unlock() const; private: HANDLE m_mutex; }; //临界区锁类 class CriSection : public ILock { public: CriSection(); ~CriSection(); virtual void Lock() const; virtual void Unlock() const; private: CRITICAL_SECTION m_critclSection; }; //锁 class CMyLock { public: CMyLock(const ILock&); ~CMyLock(); private: const ILock& m_lock; }; #endif

Lock.cpp

[cpp]view plaincopyprint? #include"Lock.h" //--------------------------------------------------------------------------- //创建一个匿名互斥对象 Mutex::Mutex(){m_mutex=::CreateMutex(NULL,FALSE,NULL);}//销毁互斥对象,释放资源 Mutex::~Mutex(){::CloseHandle(m_mutex);}//确保拥有互斥对象的线程对被保护资源的独自访问 voidMutex::Lock()const{DWORDd=WaitForSingleObject(m_mutex,INFINITE);}//释放当前线程拥有的互斥对象,以使其它线程可以拥有互斥对象,对被保护资源进行访问 voidMutex::Unlock()const{::ReleaseMutex(m_mutex);}//--------------------------------------------------------------------------- //初始化临界资源对象 CriSection::CriSection(){::InitializeCriticalSection(&m_critclSection);}//释放临界资源对象 CriSection::~CriSection(){::DeleteCriticalSection(&m_critclSection);}//进入临界区,加锁 voidCriSection::Lock()const{::EnterCriticalSection((LPCRITICAL_SECTION)&m_critclSection);}//离开临界区,解锁 voidCriSection::Unlock()const{::LeaveCriticalSection((LPCRITICAL_SECTION)&m_critclSection);}//--------------------------------------------------------------------------- //利用C++特性,进行自动加锁 CMyLock::CMyLock(constILock&m):m_lock(m){m_lock.Lock();}//利用C++特性,进行自动解锁 CMyLock::~CMyLock(){m_lock.Unlock();}

#include "Lock.h" //--------------------------------------------------------------------------- //创建一个匿名互斥对象 Mutex::Mutex() { m_mutex = ::CreateMutex(NULL, FALSE, NULL); } //销毁互斥对象,释放资源 Mutex::~Mutex() { ::CloseHandle(m_mutex); } //确保拥有互斥对象的线程对被保护资源的独自访问 void Mutex::Lock() const { DWORD d = WaitForSingleObject(m_mutex, INFINITE); } //释放当前线程拥有的互斥对象,以使其它线程可以拥有互斥对象,对被保护资源进行访问 void Mutex::Unlock() const { ::ReleaseMutex(m_mutex); } //--------------------------------------------------------------------------- //初始化临界资源对象 CriSection::CriSection() { ::InitializeCriticalSection(&m_critclSection); } //释放临界资源对象 CriSection::~CriSection() { ::DeleteCriticalSection(&m_critclSection); } //进入临界区,加锁 void CriSection::Lock() const { ::EnterCriticalSection((LPCRITICAL_SECTION)&m_critclSection); } //离开临界区,解锁 void CriSection::Unlock() const { ::LeaveCriticalSection((LPCRITICAL_SECTION)&m_critclSection); } //--------------------------------------------------------------------------- //利用C++特性,进行自动加锁 CMyLock::CMyLock(const ILock& m) : m_lock(m) { m_lock.Lock(); } //利用C++特性,进行自动解锁 CMyLock::~CMyLock() { m_lock.Unlock(); }

下边是测试代码

[cpp]view plaincopyprint? //MyLock.cpp:定义控制台应用程序的入口点。 // #include<iostream> #include<process.h> #include<time.h> #include"Lock.h" usingnamespacestd;#defineENABLE_MUTEX #defineENABLE_CRITICAL_SECTION #ifdefined(ENABLE_MUTEX) //创建一个互斥对象类型锁 Mutexg_Lock;#elifdefined(ENABLE_CRITICAL_SECTION) //创建一个临界区类型锁 CriSectiong_Lock;#endif voidLockCompare(int&iNum){CMyLocklock1(g_Lock);iNum++;}//线程函数 unsignedint__stdcallStartThread(void*pParam){char*pMsg=(char*)pParam;if(!pMsg){return(unsignedint)1;}CMyLocklock2(g_Lock);clock_ttStart,tEnd;tStart=clock();intiNum=0;for(inti=0;i<100000;i++){LockCompare(iNum);}tEnd=clock();#ifdefined(ENABLE_MUTEX) cout<<"Thelocktypeismutex,time="<<(tEnd-tStart)<<"ms."<<endl;#elifdefined(ENABLE_CRITICAL_SECTION) cout<<"Thelocktypeiscriticalsection,time="<<(tEnd-tStart)<<"ms."<<endl;#endif return(unsignedint)0;}intmain(intargc,char*argv[]){HANDLEhThread1,hThread2;unsignedintuiThreadId1,uiThreadId2;char*pMsg1="Firstprintthread.";char*pMsg2="Secondprintthread.";//创建两个工作线程,分别打印不同的消息 hThread1=(HANDLE)_beginthreadex(NULL,0,&StartThread,(void*)pMsg1,0,&uiThreadId1);hThread2=(HANDLE)_beginthreadex(NULL,0,&StartThread,(void*)pMsg2,0,&uiThreadId2);//等待线程结束 DWORDdwRet=WaitForSingleObject(hThread1,INFINITE);if(dwRet==WAIT_TIMEOUT){TerminateThread(hThread1,0);}dwRet=WaitForSingleObject(hThread2,INFINITE);if(dwRet==WAIT_TIMEOUT){TerminateThread(hThread2,0);}//关闭线程句柄,释放资源 ::CloseHandle(hThread1);::CloseHandle(hThread2);system("pause");return0;}

// MyLock.cpp : 定义控制台应用程序的入口点。 // #include <iostream> #include <process.h> #include <time.h> #include "Lock.h" using namespace std; #define ENABLE_MUTEX #define ENABLE_CRITICAL_SECTION #if defined (ENABLE_MUTEX) //创建一个互斥对象类型锁 Mutex g_Lock; #elif defined (ENABLE_CRITICAL_SECTION) //创建一个临界区类型锁 CriSection g_Lock; #endif void LockCompare(int &iNum) { CMyLock lock1(g_Lock); iNum++; } //线程函数 unsigned int __stdcall StartThread(void *pParam) { char *pMsg = (char *)pParam; if (!pMsg) { return (unsigned int)1; } CMyLock lock2(g_Lock); clock_t tStart,tEnd; tStart = clock(); int iNum = 0; for (int i = 0; i < 100000; i++) { LockCompare(iNum); } tEnd = clock(); #if defined (ENABLE_MUTEX) cout<<"The lock type is mutex, time = "<<(tEnd - tStart)<<" ms."<<endl; #elif defined (ENABLE_CRITICAL_SECTION) cout<<"The lock type is critical section, time = "<<(tEnd - tStart)<<" ms."<<endl; #endif return (unsigned int)0; } int main(int argc, char* argv[]) { HANDLE hThread1, hThread2; unsigned int uiThreadId1, uiThreadId2; char *pMsg1 = "First print thread."; char *pMsg2 = "Second print thread."; //创建两个工作线程,分别打印不同的消息 hThread1 = (HANDLE)_beginthreadex(NULL, 0, &StartThread, (void *)pMsg1, 0, &uiThreadId1); hThread2 = (HANDLE)_beginthreadex(NULL, 0, &StartThread, (void *)pMsg2, 0, &uiThreadId2); //等待线程结束 DWORD dwRet = WaitForSingleObject(hThread1,INFINITE); if ( dwRet == WAIT_TIMEOUT ) { TerminateThread(hThread1,0); } dwRet = WaitForSingleObject(hThread2,INFINITE); if ( dwRet == WAIT_TIMEOUT ) { TerminateThread(hThread2,0); } //关闭线程句柄,释放资源 ::CloseHandle(hThread1); ::CloseHandle(hThread2); system("pause"); return 0; }

在线程函数StartThread中,循环100000次,对保护资源“iNum ”反复加锁,解锁。编译,运行5次,将每次打印的线程锁切换耗时时间记录下来。之后,将测试代码中的宏 #define ENABLE_MUTEX 注释掉,禁掉互斥锁,启用临界区锁,重新编译代码,运行5次。下边是分别是互斥锁和临界区锁耗时记录(不同机器上耗时会不同):

互斥锁

临界区锁

互斥锁总共耗时:641+686=1327 ms,而临界区锁:124+140=264 ms。显而易见,临界区锁耗时比互斥锁耗时节约了大概5倍的时间。

总结:1、在同一个进程的多线程同步锁,宜用临界区锁,它比较节约线程上下文切换带来的系统开销。但因临界区工作在用户模式下,所以不能对不同进程中的多线程进行同步。2、因互斥对象锁属于内核对象,所以在进行多线程同步时速度会比较慢,但是可以在不同进程的多个线程之间进行同步。

转自:/chexlong/article/details/7060425

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。