In the previous article, key segments are used to solve the classic multi-thread synchronization mutex problem. Due to the "thread ownership" feature, key segments can only be used for thread mutex but not for synchronization. This article describes how to use Event to solve the thread synchronization problem.
The Event principle resolves multiple threads to synchronize events, which is mainly used for waiting for notifications between threads. In kernel objects, event kernel objects are the most basic objects. They contain a count (the same as all kernel objects), a Boolean value indicating whether the event is an automatically reset event or a manually reset event, another Boolean value used to indicate whether the event is in the notified or not notified status. The event notifies you that an operation has been completed. There are two different types of event objects. One is a manual reset event, and the other is an automatic reset event. When a manually reset event is notified, all threads waiting for the event change to schedulable threads. When an automatically reset event is notified, only one thread in the thread waiting for the event changes to a schedulable thread. When one thread executes the initialization operation and notifies another thread to execute the remaining operation, the event is used most. The event is initialized to the state of not notified. After the thread completes its initialization, it sets the event to the notified State. At this time, another thread waiting for the event finds that the event has been notified, so it becomes a schedulable thread.
Event API
| Event function |
Description |
| CreateEvent |
Creates or opens a named or unnamed event object. |
| CreateEventEx |
Creates or opens a named or unnamed event object and returns a handle to the object. |
| OpenEvent |
Opens an existing named event object. |
| PulseEvent |
Sets the specified event object to the signaled state and then resets it to the nonsignaled state after releasing the appropriate number of waiting threads. |
| ResetEvent |
Sets the specified event object to the nonsignaled state. |
| SetEvent |
Sets the specified event object to the signaled state. |
OK is the basic function of Event (you can also click CSDN to view the parameters and some of them are my translations). Let's take a look at the details below. Event function Parsing
HANDLECreateEvent (
LPSECURITY_ATTRIBUTESLpEventAttributes, // Security Attribute
BOOLBManualReset, // reset mode
BOOLBInitialState, // initial state
LPCTSTRLpName // Object Name); Parameter
LpEventAttributes[Input] a pointer to the SECURITY_ATTRIBUTES structure to determine whether the returned handle can be inherited by the quilt process. If lpEventAttributes is NULL, this handle cannot be inherited. Windows NT/2000: the members in the lpEventAttributes structure specify a security token for the new event. If lpEventAttributes is NULL, the event will get a default security token.
BManualReset[Input] specify whether to manually restore or automatically restore the event object. If it is TRUE, you must use the ResetEvent function to manually restore the event state to the stateless state. If this parameter is set to FALSE, when an event is released by a waiting thread, the system automatically restores the event status to the stateless state.
BInitialState[Input] specifies the initial status of the event object. If this parameter is set to TRUE, the initial state is a signal state; otherwise, the initial state is a signal state.
LpName[Input] The name of the specified event object. It is a string pointer that ends with 0. The character format of the name is limited to MAX_PATH. The name is case sensitive. If the name specified by lpName is the same as the name of an existing named event object, the function requests EVENT_ALL_ACCESS to access the existing object. At this time, because the bManualReset and bInitialState parameters have been set in the event creation process, these two parameters will be ignored. If lpEventAttributes is a parameter that is not NULL, it determines whether the handle can be inherited, but its security descriptor members are ignored. If lpName is NULL, an unknown event object is created. If the lpName is the same as an existing signal, mutex, wait timer, job, or file ing object name, the function will fail and ERROR_INVALID_HANDLE will be returned in the GetLastError function. This is because these objects share the same namespace. After an Event is created, you can use the OpenEvent () API to obtain its Handle, use CloseHandle () to close it, and use SetEvent () or PulseEvent () to set it to have a signal, use ResetEvent () to make it have no signal, use WaitForSingleObject () or WaitForMultipleObjects () to wait for it to become a signal.
PulseEvent () is an interesting method to use. Just like the API name, it changes the status of an Event object in a pulse, from no signal to a signal and then to no signal, the entire operation is atomic. for the Event object that is automatically reset, it only releases the first thread that waits for the Event (if any), and for the Event object that is manually reset, it releases all the waiting threads.
OpenEvent
HANDLEOpenEvent (
DWORD
DwDesiredAccess
,
BOOL
BInheritHandle
,
LPCTSTR
LpName
);
Parameter description
DwDesiredAccess[In] specifies the access permission for the event object. If the object specified by the security descriptor is not allowed to call this function, the function returns a failure. This parameter must be set to the following values: EVENT_ALL_ACCESS indicates all possible permissions of the event object.
BInheritHandle[In] specifies whether the returned handle is inherited. This parameter must be set to false.
LpName[In] points to a string ending with null, the name of the event object to be opened. The name is case sensitive. Let's talk about the Event principle. The functions not mentioned above are described and parsed in detail in my previous articles! You can also refer to the second kill multithreading Article 6 typical thread synchronization Event.
Finally, we will summarize the Event (morewindows)
1. Events are kernel objects, which are dividedManual location eventAndAutomatic Location event. The Event contains a count (all kernel objects), a Boolean value indicating whether to manually set a bit Event or automatically set a bit Event, and a Boolean value indicating whether the Event is triggered.
2. events can be triggered by SetEvent (), which is set by ResetEvent () as not triggered. You can also use PulseEvent () to send an event pulse.
3. events can solve the problem of synchronization between threads, so they can also solve the problem of mutual exclusion.
The next article "C ++ typical thread synchronization Event case analysis Article 9" describes how to use Event Events to solve this typical thread synchronization problem.
We are looking forward to continuous updates! Syw_selfimip Sina Weibo address: http://weibo.com/u/2945271402
Note: The above code is compiled under VS2010!