互斥量Mutex 与 互斥量CS

来源:互联网 发布:java 内部类构造函数 编辑:程序博客网 时间:2024/06/05 08:51

Mutex 和 CS都有“线程所有权”的概念,由于Mutex是内核对象,因此可以处理不同进程中的多线程互斥问题,但是由于是内核,所以速度相比于CS会慢一些,CS相比于Mutex虽然快,但只能处理同一个进程间的多线程互斥。

下面将展示一段代码,启动50个线程,并分别打印线程的编号和一个全局的变量

using namespace std;int gNum;unsigned int __stdcall ThreadWrite(void *p);CriSection cs;int main(){const  int iCount = 50;HANDLE  handle[iCount];  gNum = 0;// 创建50个线程,每个线程中都会打印ifor(int i = 0;i<iCount;i++){handle[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadWrite, &i, 0, NULL);  }WaitForMultipleObjects(iCount, handle, TRUE, INFINITE);   return 1;}unsigned int __stdcall ThreadWrite(void *p){int i = *(int*)p;Sleep(50);gNum++;cout<<"线程编号:"<<i<<"  全局变量:"<<gNum<<endl;return 0;}

 运行结果看上去很混乱,因为,多个线程之间没有任何的互斥,大家都去对gNum执行加1操作,稍有技术功底的人都知道,为何不互斥就会导致这个问题出现,这里就不再赘述,我们可以用Mutex和CS来解决这个问题,在实际应用中,为了使用方便,还会对他们进行封装

     

#include<windows.h>class BaseLock{private:bool bLock;public:virtual ~BaseLock(){};// 必须实现,且不能在函数内改变成员变量virtual void Lock()const = 0;virtual void UnLock()const = 0;};class Mutex:public BaseLock{private:HANDLE m_mutex;public:Mutex();~Mutex();void Lock()const;void UnLock()const;};class CriSection:public BaseLock{private:CRITICAL_SECTION m_critclSection;public:CriSection();~CriSection();void Lock()const;void UnLock()const;};class Lock{private:// 此处只能使用引用const BaseLock& m_Lock;public:Lock(const BaseLock& lock);~Lock();};

#include"Lock.h"////////////////////  Mutex  /////////////////////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::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);}/////////////////////  Lock  ///////////////////////////Lock::Lock(const BaseLock& lock):m_Lock(lock){m_Lock.Lock();}Lock::~Lock(){m_Lock.UnLock();}
这样封装后,使用起来会非常方便

        

#include <process.h>  #include <iostream>#include <vector>#include"Lock.h"#include"WinTree.h"#include"A.h"using namespace std;int gNum;unsigned int __stdcall ThreadWrite(void *p);CriSection cs;int main(){const  int iCount = 50;HANDLE  handle[iCount];  gNum = 0;// 创建50个线程,每个线程中都会打印ifor(int i = 0;i<iCount;i++){handle[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadWrite, &i, 0, NULL);  }WaitForMultipleObjects(iCount, handle, TRUE, INFINITE);   return 1;}unsigned int __stdcall ThreadWrite(void *p){Lock lock(cs);int i = *(int*)p;Sleep(50);gNum++;cout<<"线程编号:"<<i<<"  全局变量:"<<gNum<<endl;return 0;}
在进行互斥时,只需调用Lock lock(cs);即可,不用关系退出和释放问题,因为对象析构的时候会进行这一步操作

0 0
原创粉丝点击