互斥对象属于内核对象,它能够确保线程拥有对单个资源的互斥访问权。互斥对象包含一个使用数量,一个线程ID,一个计数器。
其中ID用于标示系统中的哪个线程当前拥有互斥对象,计数器用于指明该线程拥有互斥对象的次数。
先讲讲互斥对象的创建,需要调用函数 CreateMutex,改函数原型如下:
HANDLE CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName )
时间片到了,不得不执行其他线程,导致其它线程也访问这个资源,这样就会造成资源错乱了。所有这里就要使用互斥对象来解
决了,利用互斥对象可以保证在一个线程访问共享资源时,其它线程不能访问该资源。具体实现就是在线程中的开始访问该资源
的代码前面调用WaitForSingleObject,当访问资源结束后再调用ReleaseMutex。
能够利用WaitForSingleObject来申请拥有权。
互斥对象的拥有权,是其处于无信号状态,假设之后线程一的时间片到了,转去执行线程二,当运行到线程二中的
WaitForSingleObject时,因为此时互斥对象处于无信号状态,而且时间间隔我们这里设为了无限,那么会一直等待该函数,直
到线程二的时间片过去,然后转去执行线程一,这样线程一便可继续访问资源,期间其它线程都没有访问过线程,当访问资源
结束后,调用ReleaseMutex释放对该互斥对象的拥有权,这样其它线程便可访问该资源了。最后附上一个实例,是孙鑫的
MFC深入详解上15.4的代码
#include<windows.h> #include<iostream> using namespace std; DWORD WINAPI Fun1Proc (LPVOID lpParameter); DWORD WINAPI Fun2Proc (LPVOID lpParameter); int index = 0; int tickets = 100; HANDLE hMutex; int main() { //int index = 0; HANDLE hThread1; HANDLE hThread2; hMutex = CreateMutex (NULL, FALSE, NULL); hThread1 = CreateThread (NULL, 0, Fun1Proc, NULL, 0, NULL); hThread2 = CreateThread (NULL, 0, Fun2Proc, NULL, 0, NULL); CloseHandle (hThread1); CloseHandle (hThread2); Sleep(4000); system("pause"); return 0; } DWORD WINAPI Fun1Proc (LPVOID lpParameter) { while (1) { WaitForSingleObject (hMutex, INFINITE); if (tickets > 0) { //Sleep(1); cout << "thread1 sell ticket : " << tickets-- << endl; } else break; ReleaseMutex (hMutex); } return 0; } DWORD WINAPI Fun2Proc (LPVOID lpParameter) { while (1) { WaitForSingleObject (hMutex, INFINITE); if (tickets > 0) { //Sleep(1); cout << "Thread2 sell ticket : " << tickets-- << endl; } else break; ReleaseMutex (hMutex); } return 0; }