Use of Mutex objects when thread synchronization
1 Multi-threading issues that occur when a resource is shared
In a program, if a different thread is working on the same object, there is a possibility of a problem caused by thread switching. For example, the following program
#include <stdio.h> #include <WinSock2.h> #include <iostream>using namespace std; #pragma comment (Lib, "Ws2_32.lib") DWORD Winapifun1proc (lpvoid lpparameter);D word winapifun2proc (lpvoid lpparameter); int index = 0;int tickets = 100;void Main () {HANDLE hThread1; HANDLE hThread2; HThread1 =createthread (null,0,fun1proc,null,0,null); HThread2 =createthread (null,0,fun2proc,null,0,null); CloseHandle (HTHREAD1); CloseHandle (HTHREAD2); Sleep (4000);} DWORD Winapifun1proc (LPVoid lpparameter) {while (TRUE) {if (tickets>0) {cout<< "Thread1 Sell ticket:" <<tickets--<<endl; } else break; } Return0;} DWORD Winapifun2proc (LPVoid lpparameter) {while (TRUE) {if (tickets>0) {COUT<< "Thread2 Sell ticket:" <<tickets--<<endl; } else break; } Return0;}
The goal we expect is that thread 1 and thread 2 will all be decremented together until it is reduced to 1. However, there is a good chance of this situation: thread 1 in the If to judge the time of Tickets=1, and then a thread switch, the value of tickets is not decremented, so in line 2 is judged true, and then Tickets--,tickets = 0, when the thread again occurs switch to thread 1, then there will be tickets--, so that tickets into 0, which is not the effect we expect.
2 Problem Solution: WaitForSingleObject
It is easy to think that it would be nice if if-else were not interrupted as a whole. The idea is correct, and then there is the appearance of the WaitForSingleObject function.
DWORD WINAPI WaitForSingleObject (_in_ HANDLE hhandle, _in_ DWORD dwmilliseconds);
<1> this function, as long as the handle points to the kernel object is not signaled, then this function will be blocked until the time is dwmilliseconds. So it's like a sentry, you have to give a pass to get past it, and then just wait.
Types of <2> handles possible
- Change notification
- Console input
- Event
- Memory Resource Notification
- Mutex
- Process
- Semaphore
- Thread
- waitable timer
Application of 3 mutex mutex on thread synchronization
<1> Creation of objects
Mutex he can ensure that threads are mutually exclusive to access individual resources. This kernel object contains a usage count, a thread ID, and a counter.
HANDLE WINAPI CreateMutex ( _in_opt_ lpsecurity_attributes lpmutexattributes, _in_ BOOL Binitialowner, _in_opt_ lpctstr lpname);
Lpmutexattributes: Specifies security, when NULL, that represents the default security
Binitialowner: True indicates that the thread that created the object has ownership of the mutex, and vice versa.
Lpname: The name of the mutex object, or null if it represents an anonymous mutex object. If a name is specified and the named mutex already exists before the CreateMutex call, the function returns a handle to the existing mutex, and the call to GetLastError will be error_already_exists.
<2> release of Object ownership
ReleaseMutex (Hanlde Hmutex);
The principle of release is who owns who is released, has several times, releases it several times, and the thread ends the operating system automatically releases
When the mutex is released, the function compares the ID of the current thread with the ID of the mutex object, and if it is the same ID, it is released once. If the IDs are not equal, then they are not freed.
The object can also be owned once, such as the following code:
Hmutex = CreateMutex (null,true,null); WaitForSingleObject (hmutex,infinite); ReleaseMutex (Hmutex); ReleaseMutex (Hmutex);
When the main thread has a mutex, the object is in an unspecified state, but when the WaitForSingleObject function requests the ownership of the mutex, because the ID is equal, it can still request ownership of the mutex, and the counter inside the mutex is incremented by 1.
Once the operating system discovers that the thread terminates but does not release the mutex, it automatically sets the thread ID of the mutex to 0 and its counter to 0.
4 Final implementation of the Code
#include <stdio.h> #include <WinSock2.h> #include <iostream>using namespace std; #pragma comment (Lib, "Ws2_32.lib") DWORD Winapifun1proc (lpvoid lpparameter);D word winapifun2proc (lpvoid lpparameter); int index = 0;int tickets = 100; HANDLE Hmutex; void Main () {HANDLE hThread1; HANDLE hThread2; Hmutex =createmutex (null,false,null); Hmutex = CreateMutex (null,true,null); WaitForSingleObject (Hmutex,infinite); ReleaseMutex (Hmutex); ReleaseMutex (Hmutex); HThread1 =createthread (null,0,fun1proc,null,0,null); HThread2 =createthread (null,0,fun2proc,null,0,null); CloseHandle (HTHREAD1); CloseHandle (HTHREAD2); Sleep (4000);} DWORD Winapifun1proc (LPVoid lpparameter) {while (TRUE) {WaitForSingleObject (Hmutex,infin ITE); if (tickets>0) {cout<< "Thread1 Sell ticket:" <<tickets--<< ;Endl } else break; ReleaseMutex (Hmutex); } Return0;} DWORD Winapifun2proc (LPVoid lpparameter) {while (TRUE) {WaitForSingleObject (Hmutex,infin ITE); if (tickets>0) {cout<< "Thread2 Sell ticket:" <<tickets--<< ; Endl; } else break; ReleaseMutex (Hmutex); } Return0;}
Application of Windows mutex object on thread synchronization