互斥量Mutex 与 互斥量CS

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个线程,每个线程中都会打印i
	for(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个线程,每个线程中都会打印i
	for(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
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

酷python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值