Windows thread synchronization and mutual exclusion technical summary

NOTE: Transfer from http://blog.csdn.net/benjiamen/article/details/1658328

1.1     Thread Synchronization Overview
Without the ability to synchronize objects and special event monitoring the operating system, the thread may be forced to use side-effects technology to synchronize itself with the special event. Without the Operating system support thread synchronization technology, will produce a lot of problems, such as: distribution of unnecessary CPU time to waste; between high and low priority thread, if the thread is responsible for low signal to reset the tasks, you may never be able to perform the reset.
1.2     Critical Area
1.2.1 Overview  
The critical area: all the synchronization object, the critical section is the easiest to use, but it can only be used to synchronize threads in a single process. Critical section allows only one thread to obtain access to a data area. Further, in the synchronization of these objects, only the critical section is not the object kernel , the operating system could not help it manage the lower member, and can not be used to manipulate the handle .
1.          Create a process in a critical area, namely CRITICAL_SECTION assigned a data structure in the process, the structure of the distribution area of the threshold must be global, so different threads of the process will be able to access it.
2.          Before using a critical section thread synchronization, InitializeCriticalSection must be called to initialize the critical section. Prior to the release of resources initialized only once.
3.          VOID EnterCriticalSection: blocking function. The function returns when the calling thread is granted ownership. In other words, the calling thread can not take ownership of the specified critical section, the thread will sleep, wake up and before the system CPU will not be assigned to it.
4.          mission critical area
5. The          BOOL LeaveCriticalSection: non-blocking function. The current thread of the critical region specified One reference count; the use count goes to zero, wait for this critical region of the other a thread will be awakened.
6.          When not need to use this critical area, use DeleteCriticalSection to free resources critical area of need. After this function is executed, you can no longer use EnterCriticalSection and LeaveCriticalSection, unless InitializeCriticalSection again initialize the critical section.
1.2.2 Note:  
1.          After the critical area allow only one thread access, each thread must call the critical region flag before a critical view of the operation area data (ie CRITICAL_SECTION a global variable) EnterCriticalSection, want to gain access to other threads will be put to sleep and before wake-up, the system stops the CPU time slice allocated for them. In other words, the critical area and can only be owned by a thread, of course, there is no thread calls EnterCriticalSection or TryEnterCriticalSection, the critical region does not belong to any thread.
2.          When the ownership of a critical section thread calls LeaveCriticalSection give up ownership, the system wakes up only one thread is waiting in, giving it ownership, other threads continue to sleep.
3.          Note that owns the critical section of the thread, and each time for this critical area of EnterCriticalSection call will be successful (in this case is also repeated calls to return immediately), and will make the critical signs (ie a CRITICAL_SECTION global variable) reference One count increase . Before another thread can own the critical section, the thread must have it call LeaveCriticalSection enough times, after the reference count drops to zero, another possible thread that owns the critical section. In other words, in normal use, a thread critical zone, calSection and LeaveCriticalSection should be used in pairs.
4.          TryEnterCriticalSection     BOOL TryEnterCriticalSection (         LPCRITICAL_SECTION lpCriticalSection from the function declaration can be discerned, the EnterCriticalSection return value is a function VOID , and here BOOL . TryEnterCriticalSection visible to the call, and we need to determine its return value. When calling TryEnterCriticalSection, if specified the critical area is not any thread (or has not been any calling thread) owns, the function will be given access to the critical section of the calling thread and return TRUE; however, if the critical section is already owned by another thread, it returns immediately FALSE value. TryEnterCriticalSection and EnterCriticalSection biggest difference between that TryEnterCriticalSection never hung threads.    );
  


1.3     synchronous with thread kernel object
1.3.1 Overview  
The critical area is well suited to serialize access to data in a process, as they are fast. But we might want to make the operation a number of other special events in the computer application program or other process performed synchronized. At this critical area powerless. We need to use the kernel objects to synchronize.
The following kernel objects can be used to synchronize threads:
1.          Process, Processes
2.          Thread, Threads
3.          File, Files
4.          console input, Console input
The          file change notification, File change notifications
6.          mutex, Mutexes
7.          semaphore, Semaphores
8. The          event (Event automatic reset and manual reset event), Events
9          may be a timer or the like (only for Window NT4 or higher), Waitable timers
10.      Jobs
Each of these objects above type can be in one of two states: the signal (to signaled) and no signal (nonsignaled). Such as processes and threads at the end of its kernel object becomes signaled, and when they are created and running, its kernel object is no signal.
1.3.2 kernel object synchronization application  
1.          When a thread get a kernel object handles a process, it can: Change process priority, get the exit code of the process; so this thread is synchronized with the end of a process, and so on.
2.          When obtaining a thread kernel object handle, it can: change the thread running, synchronized with the end of the thread, and so on.
3.          When obtaining the file handle, may be: present an asynchronous thread may be a file I / O operations and the like to obtain synchronization.
4.          console input object can be used to make thread wakes up when there is an input into the related tasks to perform, and so on.
5.          Other ??? kernel object file change notification, mutexes, semaphores, events, etc. can ??? timer, just to synchronization object exists. Accordingly, there WIN32 functions to create, open, close these objects, and these objects thread synchronization. These objects, other operations can not be executed.
1.3.3 mutex unique characteristics (cf. experiment appendix)  
Mutex objects that differs from all other kernel objects it is owned by a thread. All other synchronization objects have either signal or no signal, nothing more. The mutex objects apart from recording the current signal status, but also remember at this time that thread owns it. If a thread to give a mutex object (which is about to set to no signal state) after the end of the mutex also discarded. In this case, the mutex will always remain no signal state, because there is no other threads are able to release it by calling ReleaseMutex.
When the system finds that this case, the mutex automatically set back the signaled state. Other thread waiting for the semaphore will wake up, but instead the return value WAIT_ABANDONED WAIT_OBJECT_0 normal function. At this point, other threads can know the mutex is not being properly released.
Other, similar CRITICAL_SECTION and mutexes. The thread that owns the mutex, each call WaitForSingleObject will immediately return success, but mutex usage count will increase, the same, but also to make multiple calls ReleaseMutex reference count goes to zero, square for another thread use.
1.3.3.1 doubt            
Q: The other kernel objects when the thread terminates abnormally without releasing ownership, reset the system back to its state it? If you reset, there will be no mark, no different from the normal release, which does not have this mutex return WAIT_ABANDONED feature?
[Note: The thread has a kernel object and ownership of the thread has a kernel object , the two are different . When the said thread has a kernel object, to emphasize that when the thread terminates, if the thread that owns the right of access to the kernel object, the kernel objects will be discarded because they can not ??? reset its signal state; and thread one kernel object has the right to use, referring to the thread can call certain functions, access to the kernel object or perform certain operations on the kernel objects]
A: See "Discussion and experiment a" appendix in the back.
1.3.4   WaitForSingleObject与WaitForMultipleObjects
The main thread will use two functions to wait for them to sleep kernel object becomes signaled : that is blocking function.
DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);
DWORD WaitForMultipleObjects(
DWORD nCount,
const HANDLE* lpHandles,
BOOL bWaitAll,
DWORD dwMilliseconds
);
WaitForSingleObject, wait a specified period of time (dwMilliseconds) one kernel object becomes signaled, at this time, if the kernel object to wait has been no signal, the calling thread to sleep, otherwise continue. After this time is exceeded, the thread continues to run. Function returns the value may be: WAIT_OBJECT_0, WAIT_TIMEOUT, WAIT_ABANDONED (only when the kernel object is a mutex), WAIT_FAILED.
WaitForSingleObject WaitForMultipleObjects and similar, except that it specifies either wait list (specified by lpHandles) in several objects (determined by nCount) both become a signal, or wait a list (designated by the lpHandles) becomes an object of the signal ( determined by bWaitAll).
WaitForMultipleObjects WaitForSingleObject function and have important effects on specific kernel objects that they ??? Depending on the kernel objects, will decide whether to change the signal status of kernel objects, and performing such change; these side effects, the decision is to wait for the kernel one is awakened or all of an object to be awakened in the process or thread.
1, for process and thread kernel objects, these two functions do not produce side effects . That is, after the process or thread kernel object becomes signaled that they will stay signaled, these two functions will not attempt to change the signal status of kernel objects. In this way, all threads wait for these kernel objects will be awakened.
Of The the WaitForSingleObject function Checks The Current State of The specified Object. The If The Object ~ S State IS nonsignaled, The Calling Thread Enters The the wait State. It uses NO Processor Time the while Waiting for The Object State to Become to signaled or The Time-OUT interval The to elapse.
at The function MODIFIES at The State of some types of Synchronization Objects. Occurs only for Modification to signaled at The Object Whose State Caused at The function to return. the for Example, A semaphore at The Object of COUNT IS Decreased by One.
2, for the mutex, and auto-reset timer event objects may be automatically resets the like, these two functions will not change the status of their signals. In other words, once the objects have changed and the signal has a thread wakes up, the weight of the object is set as no-signal state. Thus, only one thread is waiting to wake up, the other waiting threads will continue to sleep.
3, for WaitForMultipleObjects function has a very important characteristic : when the state can be changed any kernel object that is passed when calling it bWaitAll is TRUE, wait until all the objects are being changed to a signal, is not waiting It is reset to non-signal state. In other words, the incoming parameters bWaitAll is TRUE, WaitForMultipleObjects unless it can obtain all of the specified object (specified by lpHandles) ownership, it does not take ownership of a single object (can not take ownership of, naturally, does not change the signal state of the object). This is to prevent deadlock . In other words, when bWaitAll is TRUE, WaitForMultipleObjects does not change the state of a signal can be changed kernel object state in the absence of access to all the objects such as ownership, any thread waiting in the same way will not wake up ?? ? but otherwise the waiting thread will be woken up.
At The WaitForMultipleObjects function Determines model types within the wait Criteria have have been at The Met. Criteria have have not been the If at The Met, at The Calling the Thread Enters the wait at The State. It uses NO Processor Time Waiting for the while at The Met Criteria to BE.
The When bWaitAll is TRUE, the function~s wait operation is completed only when the states of all objects have been set to signaled. The function does not modify the states of the specified objects until the states of all objects have been set to signaled. For example, a mutex can be signaled, but the thread does not get ownership until the states of the other objects are also set to signaled. In the meantime, some other thread may get ownership of the mutex, thereby setting its state to nonsignaled.
The function modifies the state of some types of synchronization objects. Modification occurs only for the object or objects whose signaled state caused the function to return. For example, the count of a semaphore object is decreased by one. When bWaitAll is FALSE, and multiple objects are in the signaled state, the function chooses one of the objects to satisfy the wait(
到底选择哪一个呢?天知道! ); the states of the objects not selected are unaffected.
1.3.5 automatic reset or manual reset timer event  
1.          Automatic Reset: when the kernel object becomes a signal, it is possible to obtain only one thread, the thread once, in turn kernel object becomes no signal state, other waiting threads will continue to sleep. Wait class of functions implemented by a non-automatic reset function non-signal state.
2.          Manual reset: In general, all waiting for the signal thread will wake up. Before you call the relevant function to the kernel object is set to non-signal state, kernel objects will remain in the signal state.




Published 37 original articles · won praise 204 · views 440 000 +

Guess you like

Origin blog.csdn.net/zwgdft/article/details/7276857