Unknown original source, secondhand reproduced: http://blog.sina.com.cn/s/blog_4d8205e40100gjg5.html
The critical section is the simplest synchronization object, which can only be used within the same process. It ensures that only one thread can apply for this object. |
Void initializecriticalsectioN (maid ); |
Critical Section |
Void deletecriticalsection (maid section ); |
Delete critical section |
Void entercriticalsection (maid section ); |
Entering the critical section is equivalent to applying for locking. If the critical section is being used by another thread, the function will wait for other threads to release. |
Bool tryentercriticalsection (maid section ); |
Entering the critical section is equivalent to applying for locking. Unlike entercriticalsection, if the critical section is being used by another thread, the function returns false immediately without waiting. |
Void leavecriticalsection (maid section ); |
Exit the critical section, which is equivalent to applying for unlocking |
The following sample code demonstrates how to use the critical section for Data Synchronization:
// Global variable
Int icounter = 0;
Critical_section cricounter;
DWORD threada (void * PD)
{
Int IID = (INT) PD;
For (INT I = 0; I <8; I ++)
{
Entercriticalsection (& cricounter );
Int icopy = icounter;
Sleep (100 );
Icounter = icopy + 1;
Printf ("thread % d: % d \ n", IID, icounter );
Leavecriticalsection (& cricounter );
}
Return 0;
}
// In Main Function
{
// Create a critical section
InitializecriticalsectioN (& cricounter );
// Create a thread
Handle hthread [3];
Cwinthread * pt1 = afxbeginthread (afx_threadproc) threada, (void *) 1 );
Cwinthread * pt2 = afxbeginthread (afx_threadproc) threada, (void *) 2 );
Cwinthread * pt3 = afxbeginthread (afx_threadproc) threada, (void *) 3 );
Hthread [0] = pt1-> m_hthread;
Hthread [1] = pt2-> m_hthread;
Hthread [2] = pt3-> m_hthread;
// Wait until the thread ends
// The usage of waitformultipleobjects will be discussed later.
Waitformultipleobjects (3, hthread, true, infinite );
// Delete the critical section
Deletecriticalsection (& cricounter );
Printf ("\ nover \ n ");
}
The mutex function is similar to that of the critical section, but the mutex can be named, that is, it can be used across processes. Therefore, creating mutex requires more resources. Therefore, if you only use it within a process, using the critical section will bring speed advantages and reduce resource occupation. Because the mutex is a cross-process mutex. Once created, you can open it by name.
Create mutex:
Handle createmutex (
Lpsecurity_attributes lpmutexattributes,// Security Information
Bool binitialowner, // Initial status,
// If it is set to true, it indicates that the thread that created it directly owns the mutex and does not need to apply for it again.
Lptstr lpname // Name, which can be null, but cannot be opened by other threads/processes.
);
Open an existing mutex:
Handle openmutex (
DWORD dwdesiredaccess, // Access method
Bool binherithandle, // Whether it can be inherited
Lptstr lpname // Name
);
Release the right to use mutex, but the thread that calls the function must have the right to use the mutex:
Bool releasemutex ( // Act as leavecriticalsection
Handle hmutex // Handle
);
Disable mutex:
Bool closehandle (
Handle hobject // Handle
);
If the mutex is in use, it is in the non-signal state. After the mutex is released, it becomes in the signal state. After the waiting is successful, the waitforsingleobject function sets the mutex to the non-signal state, so that other threads cannot obtain the permission and need to continue waiting. The waitforsingleobject function also supports queuing to ensure that the thread waiting for the request first obtains the right to use the object.
Int icounter = 0;
DWORD threada (void * PD)
{
Int IID = (INT) PD;
// Re-open it internally
Handle hcounterin = openmutex (mutex_all_access, false, "Sam SP 44 ");
For (INT I = 0; I <8; I ++)
{
Printf ("% d wait for object \ n", IID );
Waitforsingleobject (hcounterin, infinite );
Int icopy = icounter;
Sleep (100 );
Icounter = icopy + 1;
Printf ("\ t \ tthread % d: % d \ n", IID, icounter );
Releasemutex (hcounterin );
}
Closehandle (hcounterin );
Return 0;
}
// In Main Function
{
// Create mutex
Handle hcounter = NULL;
If (hcounter = openmutex (mutex_all_access, false, "Sam SP 44") = NULL)
{
// If no other process creates this mutex, recreate it.
Hcounter = createmutex (null, false, "Sam SP 44 ");
}
// Create a thread
Handle hthread [3];
Cwinthread * pt1 = afxbeginthread (afx_threadproc) threada, (void *) 1 );
Cwinthread * pt2 = afxbeginthread (afx_threadproc) threada, (void *) 2 );
Cwinthread * pt3 = afxbeginthread (afx_threadproc) threada, (void *) 3 );
Hthread [0] = pt1-> m_hthread;
Hthread [1] = pt2-> m_hthread;
Hthread [2] = pt3-> m_hthread;
// Wait until the thread ends
Waitformultipleobjects (3, hthread, true, infinite );
// Close the handle
Closehandle (hcounter );
}
}
The waitforsingleobject function can act on:
Mutex
Event
Semaphore
Job
Process
Thread
Waitable Timer
Console input
Mutex, semaphore, and event can all be used by a process to synchronize data. Other objects have nothing to do with data synchronization, but for the process and thread, if the process and thread are in the running status, there is no signal, and there is a signal after exiting. So we can use waitforsingleobject to wait for the process and thread to exit. (As for traffic signals, the event usage will be discussed later) we used the waitformultipleobjects function in the previous example. This function is similar to waitforsingleobject, but we can see from the name that waitformultipleobjects
The function is used to wait for multiple objects to change to a signal state. The function prototype is as follows:
DWORD waitformultipleobjects (
DWORD ncount, // Number of waiting objects
Const handle * lphandles,// Object handle array pointer
Bool fwaitall, // Waiting method,
// If it is set to true, the system returns the result only when all objects are in the signal state. If it is set to false, the system returns the result when any object changes to the signal state.
DWORD dwmilliseconds // Timeout settings, in ms. If infinite is used, the waiting period is indefinite.
);
DwmillisecondsThe value range is from 0 to 0x7fffffff or infinite-0 xffffffff.