Win32 multithreading -- mutex for thread synchronization

CRITICAL_SECTIONMutex
InitializeCriticalSection()CreateMutex()
OpenMutex()
EnterCriticalSection()WaitForSingleObject()
WaitForMultipleObjects()
MsgWaitForMultipleObjects()
LeaveCriticalSection()ReleaseMutex()
DeleteCriticalSection()CloseHandle()

 

1. create Mutex

HANDLE CreateMutex(
	LPSECURITY_ATTRIBUTES lpMutexAttributes,
	BOOL bInitialOwner,	// TRUE: the thread using CreateMutex owns the generated Mutex
	LPCTSTR lpName		// Mutex name, which can be used by other processes or threads
					    //  NULL Mutex has no name
);

Return value:
If the call succeeds, the Mutex handle is returned. At this time, GetLastError is called. If the return value is ERROR_ ALREADY_EXISTS indicates that the named Mutex already exists;
The call fails and returns NULL. At this time, GetLastError can get the specific failure reason.
When you no longer need a mutex, you can call CloseHandle() to close it Like other core objects, mutex has a reference count. Every time you call CloseHandle(), the reference count is decremented by 1. When the reference count reaches 0, mutex is automatically cleared by the system.

2. Lock a mutex

To get the ownership of a mutex, please use Win32 wait () function. Wait... () does the same thing for mu tex as EnterCriticalSection() does for critical section.
The following is the way to obtain the ownership of two Mutex:
HANDLE hMutex[2]; // Suppose it has been created
Method 1:
WaitForSingleObject(hMutex[0], INFINITE);
WaitForSingleObject(hMutex[1], INFINITE);
This is an unsafe usage because thread switching may occur after the first line of execution, resulting in a deadlock. Correct should be as method 2, either two together, or none at all.
Method 2:
WaitForMultipleObjects(hMutex, 2, INFINITE);

3. Release Mutex's ownership

BOOL ReleaseMutex( HANDLE hMutex );
A thread having a mutex is like a thread entering a critical section. Only one thread can own the mutex at a time.
If the thread has a mutex and does not call releasemutex() before the end, the mutex will not be destroyed. Instead, the mutex will be treated as "not owned" and "not fired", and the next waiting thread will be treated as wait_ ABANDONED_ 0 notification. This happens regardless of whether the thread ends because of ExitThread() or because of a crash. If another thread is waiting for this mutex with WaitForMultipleObjects(), the function also returns a value between wait_ ABANDONED_ Between 0 and (WAIT_ABANDONED_0_n +1), where n refers to the number of elements of the handle array. The thread can know which mutex is abandoned according to this value. As for WaitForSingleObject(), it just returns wait_ ABANDONED_ 0

4. Solve critical_ Deadlock problem of section

Whenever you want to lock more than one synchronization object, you have the potential cause of deadlock. If all objects are always locked at the same time, the problem can be solved.

#0001 struct Node
#0002 {
#0003 	struct Node *next;
#0004 	int data;
#0005 };
#0006
#0007 struct List
#0008 {
#0009 	struct Node *head;
#0010 	HANDLE hMutex;
#0011 };
#0012
#0013 struct List *CreateList()
#0014 {
#0015 	List *list = (List *)malloc(sizeof(struct List));
#0016 	list->head = NULL;
#0017 	list->hMutex = CreateMutex(NULL, FALSE, NULL);
#0018 	return list;
#0019 }
#0020
#0021 void DeleteList(struct List *list)
#0022 {
#0023 	CloseHandle(list->hMutex);
#0024 	free(list);
#0025 }
#0026
#0027 void SwapLists(struct List *list, struct List *list2)
#0028 {
#0029 	struct List *tmp_list;
#0030 	HANDLE arrhandles[2];
#0031
#0032 	arrhandles[0] = list1->hMutex;
#0033 	arrhandles[1] = list2->hMutex;
#0034 	WaitForMultipleObjects(2, arrHandles, TRUE, INFINITE);
#0035 	tmp_list = list1->head;
#0036 	list1->head = list2->head;
#0037 	list2->head = tmp_list;
#0038 	ReleaseMutex(arrhandles[0]);
#0039 	ReleaseMutex(arrhandles[1]);
#0040 }

5. Question

5.1 can mutex be used as follows:

Mutex Can it be used as follows:
void function()
{
	WaitForMultipleObjects(hMutex, 1, INFINITE);
	// do something
	{
		WaitForMultipleObjects(hMutex, 1, INFINITE);
		// do something
		ReleaseMutex(hMutex);
	}
	ReleaseMutex(hMutex);
}
Will the above program deadlock?

5.2 # Mutex solves the dining problem of philosophers

Tags: Multithreading

Posted by maxrisc on Thu, 14 Apr 2022 10:52:49 +0930