VC + + Advanced class multi-threaded article [7]---Synchronization mechanism between threads ②

Source: Internet
Author: User

//Sample code:CStringArray g_arrstring; UINT __cdecl ThreadProc (lpvoid lpparameter) { int startidx = (int) lpparameter; for (int idx = STARTIDX; idx < startidx+100; ++IDX) {  CString str;  str. Format (_t ("%d"), idx);  g_arrstring.add (str);  } return 0;}  void cthreadtestdlg::onbnclickedbtn () { for (int idx = 1; idx <=; ++idx) {  AfxBeginThread (ThreadPro C, (LPVOID) (idx*10));  }} void cthreadtestdlg::onbnclickedprintbtn () { cstring strCount; INT_ PTR ncount = G_arrstring.getcount (),  strcount.format (_t ("%d"), ncount),  messagebox (strcount);   for (Int_ptr idx = 0; idx < ncount; ++idx) {  OutputDebugString (G_arrstring.getat (IDX));  }} ////  ①, Mutex (mutex)   How to use: 1, Create a mutex: createmutex;2, open an already existing mutex: openmutex;3, get the ownership of the mutex: WaitForSingleObject, WaitForMultipleObjects, and so on, a class of waiting functions ... (May cause blocking); 4, release the ownership of the mutex: releasemutex;5, close the mutex: ClosehandLe; handle Ghmutex = NULL; CStringArray g_arrstring; UINT __cdecl ThreadProc (lpvoid lpparameter) { int startidx = (int) lpparameter; for (int idx = STARTIDX; idx < startidx+100; ++IDX) {  CString str;  str. Format (_t ("%d"), idx);   DWORD dwwaitresult = WaitForSingleObject (Ghmutex, INFINITE);  switch ( Dwwaitresult)   {  case wait_abandoned:  case wait_object_0:   g_arrstring.add (str);   releasemutex (Ghmutex);   break; } //g_arrstring.add (str);  } return 0;}  void cthreadtestdlg::onbnclickedbtn () { ghmutex = CreateMutex (null, FALSE, NULL);  for (int idx = 1; IDX &L t;= 50; ++IDX) {  AfxBeginThread (ThreadProc, (LPVOID) (idx*10));  }} void cthreadtestdlg::onbnclickedprintbtn () { cstring strcount; int_ptr ncount = G_arrstring.getcount ();  strcount.format (_T ("%d"), NCount);  messagebox (Strcount);   for (int_ptr idx = 0; idx < ncount; ++idx) {  OutputDebugString (G_arrstring.getat (IDX));  }  closehandle (Ghmutex);}  ※ naming standard: mutexes can be used across processes, so its name is global to the whole system, so the naming is not too common, similar to: Mutex, Object, and so on. Best to think of some unique names and so on!   Inherent features (Pros + cons): 1, is a system core object, so there is a security descriptor pointer, run out to CloseHandle close handle, these are the common characteristics of the kernel object, 2, because it is the core object, so the execution speed than Critical Sections It is almost 100 times times slower (of course only compared); 3, because it is the core object, and can be named, so it can be used across processes, 4, the use of the right mutex does not occur deadlock, 5, in the "Wait" for a Mutex, you can specify the "end of waiting" length of time; 6, You can detect if the thread that currently owns the mutex has exited! Wait ..... The function will return: Wait_abandoned===================================================②, semaphores (semaphore)   Car Rental example analogy is very appropriate!   How to use: 1, create a semaphore: createsemaphore;2, open an already existing semaphore: opensemaphore;3, a possession of the semaphore: WaitForSingleObject, A waiting function such as waitformultipleobjects ... (may cause obstruction); 4, release the amount of possession of the semaphore: releasesemaphore;5, off semaphore: closehandle; handle ghsemaphore = NULL; UINT __cdecl ThreadProc (lpvoid lpparameter) { int startidx = (int) lpparameter; cstring StrOut; while ( TRUE) {   DWORD dwwaitresult = WaitForSingleObject (ghsemaphore, 0);  switch (dwwaitresult)   {  CasE wait_object_0:   strout.format (_t ("Thread%d:wait succeeded!"), GetCurrentThreadID ());    OutputDebugString (Strout);   releasesemaphore (Ghsemaphore, 1, NULL);    break;  case wait_timeout:   strout.format (_t ("Thread%d:wait timed out!"), GetCurrentThreadID ());    OutputDebugString (strout);   break; } } return 0;}  void cthreadtestdlg::onbnclickedbtn () { ghsemaphore = CreateSemaphore (null, ten, ten, null);  for (int idx = 1; IDX <= 20; ++IDX) {  AfxBeginThread (ThreadProc, (LPVOID) (idx*10));  }} void cthreadtestdlg::onbnclickedprintbtn () { closehandle (ghsemaphore);}  ※ naming standard: semaphores can be used across processes, so its name is global to the whole system, so the naming is not too common, similar to: Semaphore, Object, and so on. Best to think of some unique names and so on!   Inherent features (Pros + cons): 1, is a system core object, so there is a security descriptor pointer, run out to CloseHandle close handle, these are the common characteristics of the kernel object, 2, because it is the core object, so the execution speed is slightly slow (of course, compared to the comparison); 3. Because it is the core object, and can be named, so it can be used across processes, 4, Semaphore use the correct situation will not occur deadlock, 5, in the "Wait" for a semaphore, you can specify the "end of the waiting" length of time, 6, non-exclusive possession,Unlike Critical Sections and mutexes, these two are exclusive possessions, that is, only a single thread can get the target and have the right to operate at the same time, and semaphores is not so, there are multiple threads to get the target and operate at the same time!   So, this inside asks everybody a question, if still uses the signal quantity way to do before adds the node synchronization to the CStringArray can? ===================================================③, Event Objects (events)   event mode is the most flexible synchronization mechanism, Because his state is entirely up to you, not like the state of a Mutex and semaphores is changed by the invocation of a function like:  waitforsingleobject, so you can tell the Event object exactly what to do? And when to do it!    usage: 1, create an Event object: createevent;2, open an already existing event object: Openevent;3, get possession of the event: WaitForSingleObject function (may cause blocking); 4. Release the possession of the event (set to fire (signaled) state for the other waiting threads to wake up): Setevent;5, manual to Non-excitation (no signal) Status: RESETEVENT6, closing event object handle:closehandle;  inherent features (pros + Disadvantage): 1, is a system core object, so there is a security descriptor pointer, run out to CloseHandle close handle, these are the common characteristics of the kernel object, 2, because it is the core object, so the execution speed is slightly slow (of course, compared); 3, because it is the core object, and can be named, So it can be used across processes, 4, usually used for overlapped I/O or used to design some custom synchronization objects.   #include <windows.h> #include <stdio.h>  #define ThreadCount 4 handle ghglobalwriteevent; HANDLE Ghreadevents[threadcount]; dword WINAPI ThreadProc (LPVOID);  void createeventsandthreads (void) {    HANDLE hthread;    DWORD i, dwthreadid;    //Create a Manual-reset event object. The master thread sets   /nonsignaled when it writes to the shared buffer.     Ghgloba Lwriteevent = CreateEvent (        NULL,//default security attributes        TRUE ,//Manual-reset event        TRUE,//Initial state is signaled        TEXT ("Wri Teevent ")//Object name       );     if (ghglobalwriteevent = = NULL)     {&N Bsp     printf ("CreateEvent failed (%d) \ n", GetLastError ());        return;    }    Else if (getlasterror () = = error_already_exists)     {        printf ("Named Event already exists.\n ");        return;   }    //Create multiple thread S and an Auto-reset event Object   //For each thread. Each thread sets their event object to   //signaled when it's not reading from the shared buffer.   & nbsp for (i = 0; i < threadcount; i++)     {       //Create the Auto-reset event        Ghreadevents[i] = CreateEvent (            NULL,//No security attributes&nbsp ;           FALSE,//Auto-reset event            TRUE,//Initial St Ate is signaled            NULL); Object not named         if (ghreadevents[i] = = NULL)         {  &nbsp ;         printf ("CreateEvent failed (%d) \ n", GetLastError ());            return;       }         hthread = CreateThread (null,      &NB Sp     0,            threadproc,            &ghreadevents[i],//pass event hand le            0,            &dwthreadid);   &nbs P     if (hthread = = NULL)         {            printf ("Createthr EAD failed (%d) \ n ", GetLastError ());            return;       }  & nbsp }} void writetobuffer (void) {    DWORD Dwwaitresult, i;    //Reset ghglobalwriteevent to N Onsignaled, to block readers     if (! ResetEvent (ghglobalwriteevent))     {        printf ("ResetEvent failed (%d) \ n", GetLastError ());        return;   }    //Wait for all reading threads to F Inish reading     Dwwaitresult = waitformultipleobjects (      &NBSP ThreadCount,//number of handles in array        ghreadevents,//array of read-event handles  & nbsp     TRUE,//wait until all is signaled        INFINITE); Indefinite wait     switch (dwwaitresult)     {       //All read-event OB Jects were signaled        case wait_object_0:           //Todo:write To the GKFX buffer            printf ("Main thread writing to the shared buffer...\n"); &nb Sp           break;        //An error occurred        default:            printf ("Wait Error:%d\n", GetLastError ());            ExitProcess (0);   }    //Set ghglobalwriteevent to signaled     I F (! SetEvent (ghglobalwriteevent))   &NBsp {        printf ("SetEvent failed (%d) \ n", GetLastError ());        exitprocess (0);    }    //Set all read events to signaled    for (i = 0; i < threadcount; i++) &nbs P       if (! SetEvent (Ghreadevents[i])         {            ("SetEvent failed (%d) \ n ", GetLastError ());            return;       }} void Closeev Ents () {    int i;     for (i=0; i < threadcount; i++)         CloseHandle ( Ghreadevents[i]);     CloseHandle (ghglobalwriteevent);}  void Main () {    int i;    //todo:create the shared buffer    //Create T He events and ThreadCount threads to read from the buffer     createeventsandthreads ();     Write to the buffer three times, just For test purposes     for (i=0; i < 3; i++)         Writetobuffer ();     Close the events     closeevents ();}  dword WINAPI ThreadProc (lpvoid lpparam) {    DWORD dwwaitresult;    HANDLE hevents[2]; & nbsp   Hevents[0] = * (handle*) Lpparam; Thread ' s read event    hevents[1] = ghglobalwriteevent; Global Write event     Dwwaitresult = waitformultipleobjects (        2,//number of Handles in array        hevents,//array of event handles        TRUE,//wait T Ill all is signaled        INFINITE); Indefinite wait     switch (dwwaitresult)     {       //Both Event Object S were signaled        case wait_object_0:           //Todo:read from The shared buffer      &NBSP;     printf ("Thread%d reading from buffer...\n",                  and nbsp GetCurrentThreadID ());            break;        //An error Occurr ed        default:            printf ("Wait Error:%d\n", GetLastError ()) ;            ExitThread (0);   }    //Set The Read event to Signa led     if (! SetEvent (Hevents[0]))     {        printf ("SetEvent failed (%d) \ n", GetLastError ());        ExitThread (0);   }     return 1;}  ===================================================※※※ Small jobs: The Mutex, semaphores, Event is also encapsulated in MFC, so try to use CMutex, CSemaphore, CEvent and other types of synchronization between threads will be more convenient! -------------------------------------End-------------------------------------------

VC + + Advanced class multi-threaded article [7]---Synchronization mechanism between threads ②

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.