Content from: http://blog.csdn.net/morewindows/article/details/7823572
I. What is the "abandonment" problem
Before we talked about the mutex being able to handle the "abandonment" problem, the following text is quoted:
Mutexes are often used for thread mutexes between multiple processes, so it has a more useful feature than critical segments-the handling of " abandonment " situations. For example, if a thread that occupies a mutex terminates unexpectedly before calling ReleaseMutex () to trigger a mutex (equivalent to the mutex being "abandoned"), will all threads waiting for this mutex be caught in an infinite wait process because the mutex cannot be triggered? This is obviously unreasonable. Since the thread that occupies a mutex is terminated, it is sufficient to prove that it is no longer using the resources protected by the mutex, so these resources are fully and should be used by other threads. Therefore, in this " abandonment " case, the system automatically sets the internal thread ID of the mutex to 0, and its recursive counter is reset to 0, indicating that the mutex is triggered. Then the system will "fairly" select a waiting thread to complete the Dispatch (WaitForSingleObject () of the selected thread will return WAIT_ABANDONED_0).
The problem with "abandonment" can be seen--whether the process of owning a resource terminates unexpectedly and the other processes waiting for that resource are aware.
Two "Abandonment" Issues in key sections
Critical segments are simple on this issue-because critical segments cannot be used across processes, critical segments do not need to deal with "abandonment" issues.
Three event, mutex, semaphore "abandonment" problem
Events, mutexes, semaphores are kernel objects that can be used across processes. After a process creates a named event, other processes can call OpenEvent () and pass in the name of the event to get a handle to the event. So events, mutexes, and semaphores all encounter "abandonment" issues. We already know that mutexes can handle "abandonment", and then we'll look at whether events and semaphores can handle "abandonment" issues. Similar to the experiment done on the mutex, the following also tests the events and semaphores:
1. Create two processes.
2. Process one creates an event that is initially not triggered and then waits for the key, pressing Y to end the process after the event is triggered, or a direct exit to indicate that the process has terminated unexpectedly.
3. The process two obtains the handle of the event first, then calls WaitForSingleObject () to wait for this event for 10 seconds, in which case the output "received signal" if the event has already been triggered, otherwise the output "does not receive a signal within the specified time". If the process terminates unexpectedly during the wait, the output "the process that owns the event terminates unexpectedly". The signal volume is tested in a similar way.
First look at the event:
#include <stdio.h>#include<conio.h>#include<Windows.h>ConstTCHAR str_event_name[] = TEXT ("my_event");intMain () {HANDLE hevent=CreateEvent (NULL, False, False, Str_event_name); printf ("event has been created, now press Y to trigger the event, press other key to terminate the process \ n"); Charch; scanf ("%c", &ch); if(ch! ='y') Exit (0); SetEvent (hevent); printf ("event has been triggered \ n"); CloseHandle (hevent); return 0;}
#include <stdio.h>#include<windows.h>ConstTCHAR str_event_name[] = TEXT ("my_event");intMain () {HANDLE hevent=openevent (event_all_access, TRUE, str_event_name); if(Hevent = =NULL) {printf ("failed to open event \ n"); return 0; } printf ("waiting ... \ n"); DWORD Dwresult= WaitForSingleObject (hevent,Ten* +); Switch(dwresult) { Casewait_abandoned:printf ("the process that owns the event terminates unexpectedly \ n"); Break; Casewait_object_0:printf ("I 've received a signal \ n"); Break; Casewait_timeout:printf ("not receiving a signal within the stipulated time \ n"); Break; } closehandle (hevent); return 0; }
It can be seen that process two failed to perceive the unexpected termination of the process, stating that the event could not handle the "abandonment" issue.
Let's try the semaphore again below.
#include <stdio.h>#include<conio.h>#include<Windows.h>ConstTCHAR str_semaphore_name[] = TEXT ("My_semaphore");intMain () {HANDLE Hsemaphore= CreateSemaphore (NULL,0,1, Str_semaphore_name); printf ("Semaphore has been created, now press Y to trigger the semaphore, press other key to terminate the process \ n"); Charch; scanf ("%c", &ch); if(ch! ='y') Exit (0); ReleaseSemaphore (Hsemaphore,1, NULL); printf ("event has been triggered \ n"); CloseHandle (Hsemaphore); return 0;}
#include <stdio.h>#include<windows.h>ConstTCHAR str_semaphore_name[] = TEXT ("My_semaphore");intMain () {HANDLE Hsemaphore=OpenSemaphore (semaphore_all_access, TRUE, str_semaphore_name); if(Hsemaphore = =NULL) {printf ("failed to open event \ n"); return 0; } printf ("waiting ... \ n"); DWORD Dwresult= WaitForSingleObject (Hsemaphore,Ten* +); Switch(dwresult) { Casewait_abandoned:printf ("the process that owns the event terminates unexpectedly \ n"); Break; Casewait_object_0:printf ("I 've received a signal \ n"); Break; Casewait_timeout:printf ("not receiving a signal within the stipulated time \ n"); Break; } closehandle (Hsemaphore); return 0; }
It can be seen that process two failed to perceive the process of an unexpected termination, indicating that the semaphore and the event can not deal with the "abandonment" problem.
Four Summary of the "abandonment" problem
The experiment in this paper shows that the mutex can deal with the situation of "abandonment", and the event and Semaphore cannot solve the situation.
The reason why the mutex can deal with the "abandonment" problem is that it has the concept of "thread ownership". In the system, once the thread end, the system will determine whether there is a mutex is occupied by the threads, if there is, the system will be the mutex object inside the thread ID number will be set to NULL, the recursive count is set to 0, which means that the mutex is no longer occupied by any thread, is in the trigger state. Other threads waiting for this mutex will be able to execute smoothly. As to how threads get Mutex "thread ownership", the MSDN description for--a thread obtainsownership of A mutex either by creating it with the BinitialownerPA Rameter set to TRUE or by specifying it handle in a call toone of the wait functions.
"Multithreading" Learning 13