"Multithreading" Learning 5

Source: Internet
Author: User
Tags function prototype

Content from: http://blog.csdn.net/morewindows/article/details/7445233

This article describes the use of event events to try to resolve this thread synchronization problem.

Let's start by describing how to use events. Event events is actually a kernel object, and it's very handy to use. Some commonly used functions are listed below.

The first of the CreateEvent

function function: Create Event

Function Prototypes:

HANDLE CreateEvent (

lpsecurity_attributes Lpeventattributes,

BOOL bManualReset,

BOOL Binitialstate,

LPCTSTR lpname

);

Function Description:

The first parameter represents the security control, which is typically passed directly to null.

The second parameter determines whether the event is set manually or automatically, passing in true to indicate a manual setting, and passing in false to indicate an automatic position. If set to Automatic, resetevent() is called automatically after the event is called WaitForSingleObject() to cause the event to become non-triggering. For a small analogy, the manual set-up event is equivalent to the classroom door, and once the classroom door is opened (triggered), anyone can enter until the teacher closes the classroom door (the event becomes not triggered). Automatic set-up event is equivalent to the hospital X-ray room door, the door can only enter a person after opening, the person will be closed door, the other people can not enter unless the doors reopened (the event is re-triggered).

The third parameter represents the initial state of the event, and an incoming Trur indicates that it has been triggered.

The fourth parameter represents the name of the event, and passing NULL indicates an anonymous event.

A second openevent

function function: Gets an event handle by name.

Function Prototypes:

HANDLE openevent (

DWORD dwDesiredAccess,

BOOL bInheritHandle,

LPCTSTR lpname//Name

);

Function Description:

The first parameter represents the access permission, which is typically passed to event_all_access for an event. Detailed explanations can be viewed in the MSDN documentation.

The second parameter represents the inheritance of the event handle, which is generally passed in true.

The third parameter represents a name, and each thread in a different process can make sure that they access the same event by name.

A third SetEvent

function function: Trigger event

Function prototype:BOOL SetEvent(HANDLE hevent);

Function Description: After each trigger, there must be one or more threads in the waiting state to become a scheduled state.

Fourth one ResetEvent

function function: Set event to end trigger

Function prototype:BOOL resetevent(HANDLE hevent);

Cleanup and destruction of the last event

Because the event is a kernel object, you can use CloseHandle() to complete the cleanup and destruction.

Set up an event and a critical segment in the classic multithreaded problem. The main thread and the child thread are synchronized with the event handling, and the key section is used to deal with the mutual exclusion between the sub-threads. See the code:

#include <stdio.h>#include<process.h>#include<Windows.h>Longg_nnum;unsignedint__stdcall Fun (void*PPM);Const intThread_num =Ten;//events and critical segmentsHANDLE g_hthreadevent; critical_section G_csthreadcode;intMain () {//Initialize event and critical segment auto-position, initial no-trigger anonymous eventG_hthreadevent =CreateEvent (null, FALSE, FALSE, NULL); InitializeCriticalSection (&G_csthreadcode);    HANDLE Handle[thread_num]; G_nnum=0; inti =0;  while(I <thread_num) {Handle[i]= (HANDLE) _beginthreadex (NULL,0, Fun, &i,0, NULL); WaitForSingleObject (G_hthreadevent, INFINITE); //wait for event firingi++;    } waitformultipleobjects (Thread_num, handle, TRUE, INFINITE); //destroying events and critical segmentsCloseHandle (g_hthreadevent); DeleteCriticalSection (&G_csthreadcode); return 0;} unsignedint__stdcall Fun (void*PPM) {    intNthreadnum = * (int*) PPM; SetEvent (g_hthreadevent); //Triggering EventsSleep ( -); EnterCriticalSection (&G_csthreadcode); G_nnum++; Sleep (0); printf ("Thread number%d global resource value is%d\n", Nthreadnum, g_nnum); LeaveCriticalSection (&G_csthreadcode); return 0;}

As can be seen, the classic thread synchronization problem has been satisfactorily solved-the output of the thread number is not duplicated, indicating that the main thread and the child thread reached synchronization. The output of the global resource is incremented, indicating that each child thread has mutually exclusive access to and output the global resource.

Note: As long as the number does not repeat the success, do not need to increment the number, otherwise it is not parallel

Now we know how to use the event, but learning should be in-depth learning, not to mention Microsoft to the event also provides the PulseEvent() function, so then continue to dig deep down the event, see if it has any secret.

Let's take a look at the prototype of this function:

Fifth one PulseEvent

function function: Set the event to not fire immediately after the event is triggered, equivalent to triggering an event pulse.

Function prototype:BOOL PulseEvent(HANDLE hevent);

Function Description: This is an infrequently used event function, which is equivalent to SetEvent() immediately after calling ResetEvent(); The situation can be divided into two types:

1. For manual set-up events, all the threads that are in the waiting state become scheduled.

2. For an auto-set event, only one of the threads that are in the waiting state can become a scheduled state.

Subsequent events are triggered at the end. The function is not stable because it is not possible to predict which threads are waiting while calling PulseEvent ().

Best not to use PulseEvent ()!

The following is an example of triggering an event pulse pulseevent (), the main thread initiates 7 sub-threads, where 5 threads sleep (10) After a wait function (called a fast thread) is called on an event, and another 2 threads sleep (100) A wait function (called a slow thread) is also called on the event. The main thread starts all the child threads and then sleep (50) guarantees that 5 fast threads are in the waiting state. At this point, if the main thread triggers an event pulse, the 5 threads will execute smoothly for the manual set-up event. For an auto-set event, one of the 5 threads will execute smoothly. The 2 slow threads miss the event pulses because of sleep (100), regardless of the manual set-up or auto-set events, so slow threads go into a wait state and fail to execute smoothly.

The code is as follows:

#include <stdio.h>#include<conio.h>#include<process.h>#include<Windows.h>HANDLE g_hthreadevent;//Fast ThreadingUnsignedint__stdcall Fastthreadfun (void*PPM) {Sleep (Ten); printf ("%s started \ n", (PSTR) PPM);    WaitForSingleObject (G_hthreadevent, INFINITE); printf ("%s Wait until event is triggered to end successfully \ n", (PSTR) PPM); return 0;}//Slow ThreadsUnsignedint__stdcall Slowthreadfun (void*PPM) {Sleep ( -); printf ("%s started \ n", (PSTR) PPM);    WaitForSingleObject (G_hthreadevent, INFINITE); printf ("%s Wait until event is triggered to end successfully \ n", (PSTR) PPM); return 0;}intMain () {BOOL bManualReset=FALSE; G_hthreadevent=CreateEvent (null, bManualReset, FALSE, NULL); if(bManualReset = =TRUE) {printf ("Manual Set-up event is currently used \ n"); }    Else{printf ("Auto-set event currently used \ n"); }    Charszfastthreadname[5][ -] = {"Fast Thread","Fast Threading 1001","Fast Threading 1002","Fast Threading 1003","Fast Threading 1004"}; Charszslowthreadname[2][ -] = {"Slow thread 196","Slow Thread 197"}; inti;  for(i =0; I <5; i++) _beginthreadex (NULL,0, Fastthreadfun, Szfastthreadname[i],0, NULL);  for(i =0; I <2; i++) _beginthreadex (NULL,0, Slowthreadfun, Szslowthreadname[i],0, NULL); Sleep ( -);//ensure that fast threads are all startedprintf"now the main thread triggers an event pulse-PulseEvent () \ n"); PulseEvent (g_hthreadevent);//calling PulseEvent () is equivalent to calling the following two sentences simultaneously//SetEvent (g_hthreadevent); //resetevent (g_hthreadevent); Sleep ( the); printf ("time is up, the main thread ends running \ n");      CloseHandle (g_hthreadevent); return 0; }

Automatic reset event, the result of the operation is as follows:

Manual Position Events

Final summary of event events

1. Events are kernel objects, and events are divided into manual set-up events and auto- set events. Inside event Events It contains a usage count (all kernel objects have), a Boolean value that indicates whether a manual set-bit event or an auto-set event, and another Boolean value to indicate whether the event has a trigger.

2. Events can be triggered by setevent () and set by ResetEvent () to not be triggered. An event pulse can also be emitted by pulseevent ().

3. Events can resolve inter-thread synchronization issues and therefore can also resolve mutex issues.

"Multithreading" Learning 5

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.