Usage method:
1. Create a mutex.
2. Open an existing mutex.
3. Obtain ownership of mutexes: WaitForSingleObject, WaitForMultipleObjects and other waiting functions... (may cause obstruction);
4. Release Mutex;
5. Close the mutex: CloseHandle;
Function prototype:
HANDLE WINAPI CreateMutex( __in_opt LPSECURITY_ATTRIBUTES lpMutexAttributes, __in BOOL bInitialOwner, __in_opt LPCTSTR lpName );
lpMutexAttributes: The first parameter represents security control and is typically passed directly into NULL.
The second parameter of bInitial Owner is used to determine the initial owner of the mutex.
If TRUE is passed in, the thread ID number of the thread that created it will be recorded and the recursive count set to 1. Because the thread ID is non-zero, the mutex is in an untouched state, indicating that the mutex is owned by the creating thread. If FALSE is passed in, the thread ID number inside the mutex object is set to NULL and the recursive count is set to 0, which means that the mutex is not occupied by any thread and is in the trigger state.
The third parameter of lpName is used to set the name of the mutex. Threads in multiple processes use the name to ensure that they access the same mutex.
_Naming criteria: Mutex can be used across processes, so its name is global for the whole system, so the naming should not be too common, such as: Mutex, Object, etc.
Better think of some unique names and so on!
Inherent characteristics (advantages + disadvantages):
1. It is a core object of the system, so there are security description pointers and CloseHandle closes the handle when it is used up. These are common features of the kernel objects.
2. Because it is the core object, the execution speed will be almost 100 times slower than Critical Sections (only comparatively speaking, of course).
3. Because it is the core object and can be named, it can be used across processes.
4. There will be no deadlock when Mutex is used correctly.
5. When "waiting" for a Mutex, you can specify the length of "ending the waiting".
6. Can detect whether the thread that currently owns the mutex ownership has exited? Wait... The function returns: WAIT_ABANDONED
#include <iostream>
#include <windows.h>
using namespace std;
HANDLE g_hMutex = NULL;
const int g_Number = 3;
DWORD WINAPI ThreadProc1(__in LPVOID lpParameter);
DWORD WINAPI ThreadProc2(__in LPVOID lpParameter);
DWORD WINAPI ThreadProc3(__in LPVOID lpParameter);
int main()
{
g_hMutex = CreateMutex(NULL, FALSE, NULL);
//TRUE represents that the main thread owns the mutex object, but the main thread does not release the object mutex object who owns and who releases it.
// FLASE represents that no thread currently owns this mutex
HANDLE hThread[g_Number] = { 0 };
int first = 1, second = 2, third = 3;
hThread[0] = CreateThread(NULL, 0, ThreadProc1, (LPVOID)first, 0, NULL);
hThread[1] = CreateThread(NULL, 0, ThreadProc2, (LPVOID)second, 0, NULL);
hThread[2] = CreateThread(NULL, 0, ThreadProc3, (LPVOID)third, 0, NULL);
WaitForMultipleObjects(g_Number, hThread, TRUE, INFINITE);
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
CloseHandle(hThread[2]);
//CloseHandle(g_hMutex);
return 0;
}
DWORD WINAPI ThreadProc1(__in LPVOID lpParameter)
{
WaitForSingleObject(g_hMutex, INFINITE);//Waiting Mutual Exclusion
for (int i = 0; i < 50; i++)
cout << (int)lpParameter;
cout << endl;
ReleaseMutex(g_hMutex);//Release Mutual Exclusion
return 0;
}
DWORD WINAPI ThreadProc2(__in LPVOID lpParameter)
{
WaitForSingleObject(g_hMutex, INFINITE);//Waiting Mutual Exclusion
for (int i = 0; i < 50; i++)
cout << (int)lpParameter;
cout << endl;
ReleaseMutex(g_hMutex);//Release Mutual Exclusion
return 0;
}
DWORD WINAPI ThreadProc3(__in LPVOID lpParameter)
{
WaitForSingleObject(g_hMutex, INFINITE);//Waiting Mutual Exclusion
for (int i = 0; i < 50; i++)
cout << (int)lpParameter;
cout << endl;
ReleaseMutex(g_hMutex);//Release Mutual Exclusion
return 0;
}