[Windows c++] CRITACAL_SECTION 和 Mutex 的安全性对比

例子代码:

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Windows.h>
#include <process.h>
#include <string>
#include <iostream>

using namespace std;

CRITICAL_SECTION protector;
int a = [](CRITICAL_SECTION& cs){
	InitializeCriticalSection(&cs);
	return 0;
}(protector);

int cnt_1 = 0;
int cnt_2 = 0;

HANDLE mutex= CreateMutex(NULL,FALSE,NULL);

unsigned int __stdcall thread1(void* ptr)
{
	while (1){
		//EnterCriticalSection(&protector);	//进入临界区
		WaitForSingleObject(mutex,INFINITE);
		cout << "thread 1 进入临界区" << endl;			//输出
		if (cnt_1 == 5) return 0;			//30秒后直接退出,同时不离开临界区,这会导致thread2锁住,因此2号线程将不再输出内容
		Sleep(3000);						//等待
		//LeaveCriticalSection(&protector);	//离开临界区
		ReleaseMutex(mutex);
		cout << "thread 1 离开临界区" << endl;			//输出
		cnt_1++;
		Sleep(10);							//让另外一个线程抢临界区
	}
	return 0;
}

unsigned int __stdcall thread2(void* ptr)
{
	while (1){
		//EnterCriticalSection(&protector);	//进入临界区
		WaitForSingleObject(mutex, INFINITE);
		cout << "thread 2 进入临界区" << endl;
		Sleep(3000);
		//LeaveCriticalSection(&protector);	//离开临界区
		ReleaseMutex(mutex);
		cout << "thread 2 离开临界区" << endl;
		Sleep(10);							//让另外一个线程抢临界区
	}
	return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int step1;

	unsigned int i, j;
	_beginthreadex(NULL, 0, thread1, NULL, 0, &i);
	_beginthreadex(NULL, 0, thread2, NULL, 0, &j);

	cin >> step1;

	return 0;
}

如果使用 CRITACAL_SECTION ,则在15秒后,线程2将被阻塞住;

如果使用 Mutex,则在15秒后, 线程2 将继续运行,此时只有线程而输出,因为线程1已经退出;

 

Mutex 比 CRITACAL_SECTION 安全,不会出现 “因线程终止而未对 Mutex 释放,而导致死锁场景” , 但是Mutex 比 CRITACAL_SECTION 慢。

 

重要:

仅仅在 “ 线程退出时没来得及 ReleaseMutex ” 的时候,操作系统才会回收 Mutex,然后再给其他试图获取Mutex的线程返回。

可以理解为线程退出时通知操作系统检查自己是否有占用任何核心对象,如果占用了,让操作系统标记这些对象为已经被释放,

后面的线程再去申请的时候便会被通知异常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值