Multi-thread synchronization-Event

Source: Internet
Author: User

Among all kernel objects, the event kernel object is the most basic. It contains a usage count (the same as all kernel objects) and a bool value (used to indicate whether the event is an automatic reset event or a manual reset event ), there is also a bool value (used to indicate whether the event is in the notified or not notified status ). The event can notify a thread that the operation has been completed. There are two types of event objects. One is manual resetting, and the other is automatic resetting. The difference is that 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 initialization and notifies another thread to execute the remaining operations, the event is most frequently used. In this case, the event is initialized to the state of not notified. After the thread completes its initialization, it sets the event to the notified State, another thread waiting for the event becomes a schedulable thread after the event has been notified.

The createevent () function of Windows API is used to create the event kernel object:

Handle createevent (

Psecurity_attributes PSA, // security descriptor. Look, this is a kernel object.

Bool fmanualreset,

Bool finitialstate,

Pctstr pszname );

If the fmanualreset parameter is true, it indicates the time when a manual reset is created. If it is false, it indicates that an automatic reset event is created.

When the finitialstate parameter is true, it indicates that the event is to be initialized to the notified State, and vice versa.

After the system creates an event object, createevent returns an event handle. Threads in other processes can obtain access to this object by using the same value passed in the p s z n a m e parameter, using the inheritance attribute, or use the duplicatehandle function to call createevent, or call openevent to set a name that matches the name set when createevent is called in the p szname parameter:

Handle openevent (

DWORD fdwaccess,

Bool finherit,

Pctstr pszname );

As in all cases, the closehandle () function should be called when the event kernel object is no longer needed.

Once an event has been created, you can directly control its status. Call setevent to change the event to the notified status: bool setevent (handle hevent );

When calling the resetevent function, you can change this event to the "not notified" status:

Bool resetevent (handle hevent );

When the thread successfully waits for the object, the events that are automatically reset will be automatically reset to the unnotified state. Generally, there is no need to call the resetevent function for automatically reset events because the system will automatically reset the events. This is not applicable to manually reset event objects.

A simple example:

// Global handle

Handle g_hevent;

Int winapi winmain (...)

{

// Create a manual reset event object

G_hevent = createevent (null, true, false, null );

// Generate three threads

Handle hthread [3];

DWORD dwthreadid;

Hthread [0] = _ beginthreadex (null, 0, wordcount, null, 0, & dwthreadid );

Hthread [1] = _ beginthreadex (null, 0, spellcheck, null, 0, & dwthreadid );

Hthread [2] = _ beginthreadex (null, 0, grammarcheck, null, 0, & dwthreadid );

Openfileandreadcontentsintomemory (...);

// Notify the waiting thread and tell them that my job is finished and you can start to execute it.

Setevent (g_hevent );

...

}

DWORD winapi wordcount (pvoid pvparam)

{

// Wait for the event

Waitforsingleobject (g_hevent, infinite );

// Access the memory block.

...

Return (0 );

}

DWORD winapi spellcheck (pvoid pvparam)

{

// Wait for the event

Waitforsingleobject (g_hevent, infinite );

// Access the memory block.

...

Return (0 );

}

DWORD winapi grammarcheck (pvoid pvparam)

{

// Wait until the file's data is in memory.

Waitforsingleobject (g_hevent, infinite );

// Access the memory block.

...

Return (0 );

}

When the process starts, it creates an event with no notification Status manually reset and stores the handle in a global variable. This makes it easy for other threads in the process to access the same event object.ProgramThree threads are created at the beginning. These threads are suspended after initialization and wait for the event. These threads need to wait for the file content to be read into the memory, and each thread will access the file content. One thread counts words, the other thread runs the spelling check, and the third thread runs the syntax check. The three thread FunctionsCodeEach function calls waitforsingleobject. This causes the thread to pause until the file content is read into the memory by the main thread. Once the main thread prepares the data, it calls setevent to send a notification to the event. At this time, the system enables all three auxiliary threads to enter the schedulable state, which obtain the c p u time and can access the memory block. All three threads must access the memory in read-only mode. Otherwise, a memory error occurs. This is the only reason why all three threads can run simultaneously. If there are more than three CPUs on the computer, theoretically the three threads can actually run simultaneously, so that a large number of operations can be completed in a short time.

If you use auto-reset events instead of manual reset events, the behavior characteristics of the application are very different. After the main thread calls s e t e v e n t, the system allows only one auxiliary thread to change to a schedulable state. Likewise, it cannot be guaranteed which thread the system will change to the schedulable state. The remaining two auxiliary threads will continue to wait. A thread that has changed to a schedulable state has exclusive access to the memory block.

Let's re-compile the thread function so that each function calls the s e t e v e n t function before returning (as the WI n m a I n function does ). These thread functions are now in the following form:

DWORD winapi wordcount (pvoid pvparam)

{

Waitforsingleobject (g_hevent, infinite );

...

Setevent (g_hevent );

Return (0 );

}

DWORD winapi spellcheck (pvoid pvparam)

{

Waitforsingleobject (g_hevent, infinite );

...

Setevent (g_hevent );

Return (0 );

}

DWORD winapi grammarcheck (pvoid pvparam)

{

Waitforsingleobject (g_hevent, infinite );

...

Setevent (g_hevent );

Return (0 );

}

When the main thread reads the file content into the memory, it calls the setevent function. This will make one of the three waiting threads A schedulable thread. We do not know which thread will be selected as the scheduling thread first. When this thread completes the operation, it will also call the s e t e v e n t function to make the next one scheduled. In this way, the three threads will be executed sequentially. The operating system determines the sequence. Therefore, even if every auxiliary thread accesses the memory block in read/write mode, no problem occurs. These threads are no longer required to regard data as read-only data.

This example clearly shows the difference between manual reset events and automatic reset events.

There is also a function that can be used for events:

Bool pulseevent (handle hevent );

The p u l s e v e n t function changes the event to the notified status, and then immediately changes to the not notified status, this is like calling the r e s e t e v e n t function immediately after calling s e t e v e n t function. If the p u l s e v e n t function is called on a manual reset event, any or all threads waiting for the event will become schedulable threads. If the p u l s e v e n t function is called on the automatic reset event, only one thread waiting for the event changes to a schedulable thread. If no thread is waiting for the event when an event is triggered, the event will not be affected.

 

This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/bichenggui/archive/2009/09/14/4551149.aspx

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.