临界区锁和互斥对象锁对比介绍
来源:互联网 发布:多组数据的相关性分析 编辑:程序博客网 时间:2024/06/05 01:16
在Win32平台上进行多线程编程,常会用到锁。下边用C++实现了互斥对象(Mutex)锁和临界区(CRITICAL_SECTION)锁,以加深理解和今后方便使用。代码已在VS2005环境下编译测试通过。
Lock.h
#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
#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();}
下边是测试代码
// 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;#endifvoid 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;#endifreturn (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次。下边是分别是互斥锁和临界区锁耗时记录(不同机器上耗时会不同):
互斥锁
线程Id
耗时 / ms
总计
1
141
125
125
125
125
641
2
140
125
140
125
156
686
临界区锁
线程Id
耗时 / ms
总计
1
15
16
31
31
31
124
2
31
31
31
16
31
140
互斥锁总共耗时:641+686=1327 ms,而临界区锁:124+140=264 ms。显而易见,临界区锁耗时比互斥锁耗时节约了大概5倍的时间。
总结:1、在同一个进程的多线程同步锁,宜用临界区锁,它比较节约线程上下文切换带来的系统开销。但因临界区工作在用户模式下,所以不能对不同进程中的多线程进行同步。2、因互斥对象锁属于内核对象,所以在进行多线程同步时速度会比较慢,但是可以在不同进程的多个线程之间进行同步。
0 0
- 临界区锁和互斥对象锁对比介绍
- 互斥对象锁和临界区锁性能比较
- 互斥对象锁和临界区锁性能比较
- 互斥对象锁和临界区锁性能比较
- 互斥对象锁和临界区锁性能比较
- 互斥对象锁和临界区锁性能比较
- 互斥对象锁和临界区锁性能比较
- 互斥对象锁和临界区锁性能比较
- 临界区、互斥对象、WaitForSingleObject、WaitForMultipleObjects
- 互斥和临界区的区别
- 互斥对象与临界区对象的区别
- 互斥对象,事件对象,临界区的使用比较
- 线程同步-临界区、互斥对象、事件对象区别
- C++ 临界区、互斥对象、信号量、内核事件
- 互斥对象与临界区的区别!
- 多线程同步方法:临界区、事件、信号量、互斥对象
- 线程同步的三种方法(互斥,事件,临界区) 之一 使用临界区对象
- 临界区,互斥,信号量
- 关于javaee编码问题
- UIImage from ALAsset: getting the right orientation
- 黑马程序员 发布一个虚拟复印机的小程序
- jsp界面中文乱码的解释
- 3.5
- 临界区锁和互斥对象锁对比介绍
- 第三章第十四题倒序20150419
- 原始套接字之PING(3)
- JNDI学习总结(一)——JNDI数据源的配置
- 《数据结构(C语言版)》综述
- 初学《Linux内核如何装载和启动一个可执行程序》
- maven配置文件setting.xml字段注释
- MyBatis学习总结(一)——MyBatis快速入门
- OpenFlow标准分析