例子代码:
// 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的线程返回。
可以理解为线程退出时通知操作系统检查自己是否有占用任何核心对象,如果占用了,让操作系统标记这些对象为已经被释放,
后面的线程再去申请的时候便会被通知异常。