Objective: To implement thread synchronization lock using Mutex of C ++ and Windows.
Preparation knowledge: 1. the working mechanism of the kernel object Mutex and the usage of the WaitForSingleObject function can be obtained from MSDN. 2, when two or more threads need to access a shared resource at the same time, the system needs to use a synchronization mechanism to ensure that only one thread uses the resource at a time. Mutex is a synchronization primitive that grants only one thread the exclusive access to shared resources. If a thread obtains the mutex, the second thread to obtain the mutex will be suspended until the first thread releases the mutex.
Below is the thread lock class I wrote by referring to the C ++ Sockets code of the open-source project.
Lock. h
# Ifndef _ Lock_H
# Define _ Lock_H
# Include <windows. h>
// Lock Interface Class
Class IMyLock
{
Public:
Virtual ~ IMyLock (){}
Virtual void Lock () const = 0;
Virtual void Unlock () const = 0;
};
// Mutex object lock class
Class Mutex: public IMyLock
{
Public:
Mutex ();
~ Mutex ();
Virtual void Lock () const;
Virtual void Unlock () const;
Private:
HANDLE m_mutex;
};
// Lock
Class CLock
{
Public:
CLock (const IMyLock &);
~ CLock ();
Private:
Const IMyLock & m_lock;
};
# Endif
Lock. cpp
# Include "Lock. h"
// Create an anonymous mutex object
Mutex: Mutex ()
{
M_mutex =: CreateMutex (NULL, FALSE, NULL );
}
// Destroy mutually exclusive objects and release resources
Mutex ::~ Mutex ()
{
: CloseHandle (m_mutex );
}
// Ensure that threads with mutex objects can access protected resources independently.
Void Mutex: Lock () const
{
DWORD d = WaitForSingleObject (m_mutex, INFINITE );
}
// Release mutex objects owned by the current thread so that other threads can have mutex objects and access protected resources
Void Mutex: Unlock () const
{
: ReleaseMutex (m_mutex );
}
// Use the C ++ feature for automatic locking
CLock: CLock (const IMyLock & m): m_lock (m)
{
M_lock.Lock ();
}
// Use the C ++ feature for automatic unlocking
CLock ::~ CLock ()
{
M_lock.Unlock ();
}
Below is the test code
// MyLock. cpp: defines the entry point of the console application.
//
# Include <iostream>
# Include <process. h>
# Include "Lock. h"
Using namespace std;
// Create a mutex object
Mutex g_Lock;
// Thread Functions
Unsigned int _ stdcall StartThread (void * pParam)
{
Char * pMsg = (char *) pParam;
If (! PMsg)
{
Return (unsigned int) 1;
}
// Automatically lock protected resources (the following print Statement)
// Unlock automatically before the end of the thread function
CLock lock (g_Lock );
For (int I = 0; I <5; I ++)
{
Cout <pMsg <endl;
Sleep (500 );
}
Return (unsigned int) 0;
}
Int main (int argc, char * argv [])
{
HANDLE hThread1, hThread2;
Unsigned int uiThreadId1, uiThreadId2;
Char * pMsg1 = "First print thread .";
Char * pMsg2 = "Second print thread .";
// Create two worker threads to print different messages respectively
// HThread1 =: CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) StartThread, (void *) pMsg1, 0, (LPDWORD) & uiThreadId1 );
// HThread2 =: CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) StartThread, (void *) pMsg2, 0, (LPDWORD) & uiThreadId2 );
HThread1 = (HANDLE) _ beginthreadex (NULL, 0, & StartThread, (void *) pMsg1, 0, & uiThreadId1 );
HThread2 = (HANDLE) _ beginthreadex (NULL, 0, & StartThread, (void *) pMsg2, 0, & uiThreadId2 );
// Wait until the thread ends
DWORD dwRet = WaitForSingleObject (hThread1, INFINITE );
If (dwRet = WAIT_TIMEOUT)
{
TerminateThread (hThread1, 0 );
}
DwRet = WaitForSingleObject (hThread2, INFINITE );
If (dwRet = WAIT_TIMEOUT)
{
TerminateThread (hThread2, 0 );
}
// Close the thread handle and release resources
: CloseHandle (hThread1 );
: CloseHandle (hThread2 );
System ("pause ");
Return 0;
}
Use VC2005 to compile and start the program. below is
If you check out the code in the test thread function, re-compile the code and run
CLock lock (g_Lock );
The result is as follows:
It can be seen that multi-thread synchronization can be achieved by using the Mutex encapsulation class. Because Mutex is a kernel object, the speed of multi-thread synchronization is slow. However, Mutex objects can be used to synchronize data between multiple threads of different processes.
In practical applications, we usually use the CRITICAL_SECTION key code segment. In the next blog, I will add the key code segment lock and compare the performance of Mutex and CRITICAL_SECTION.
From the chexlong Column