ACCESS转— 秒杀二十多线程第陆篇 经典线程同步 事件伊芙nt

函数作用:触发事件

 

2.对于活动置位事件,全体正处在等候状态下线程只有一个改成可调度意况。

其次个参数表示事件句柄继承性,一般传入TRUE即可。

HANDLEOpenEvent(

上一篇中采纳关键段来消除经典的八线程同步互斥难题,由于关键段的“线程全数权”天性所以首要段只好用于线程的排挤而不可能用来共同。本篇介绍用事件伊夫nt来品尝化解这一个线程同步难题。

 LPSECURITY_ATTRIBUTESlpEventAttributes,

末尾二篇《秒杀四线程第⑧篇 经典线程同步
互斥量Mutex
》和《秒杀二十多线程第⑩篇 经典线程同步 信号量Semaphore》将介绍怎么样采取互斥量和信号量来缓解这一个经典线程同步难点。欢迎大家继续秒杀四线程之旅。

ACCESS 1

  1. #include <stdio.h>  
  2. #include <process.h>  
  3. #include <windows.h>  
  4. long g_nNum;  
  5. unsigned int __stdcall Fun(void *pPM);  
  6. const int THREAD_NUM = 10;  
  7. //事件与根本段  
  8. HANDLE  g_hThreadEvent;  
  9. CRITICAL_SECTION g_csThreadCode;  
  10. int main()  
  11. {  
  12.     printf(”     经典线程同步 事件伊芙nt\n”);  
  13.     printf(” — by MoreWindows( http://blog.csdn.net/MoreWindows ) –\n\n”);  
  14.     //最先化事件和重庆大学段 自动置位,初阶无接触的匿名事件  
  15.     g_hThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);   
  16.     InitializeCriticalSection(&g_csThreadCode);  
  17.   
  18.     HANDLE  handle[THREAD_NUM];   
  19.     g_nNum = 0;  
  20.     int i = 0;  
  21.     while (i < THREAD_NUM)   
  22.     {  
  23.         handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL);  
  24.         WaitForSingleObject(g_hThread伊芙nt, INFINITE); //等待事件被触发  
  25.         i++;  
  26.     }  
  27.     WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);  
  28.   
  29.     //销毁事件和严重性段  
  30.     CloseHandle(g_hThreadEvent);  
  31.     DeleteCriticalSection(&g_csThreadCode);  
  32.     return 0;  
  33. }  
  34. unsigned int __stdcall Fun(void *pPM)  
  35. {  
  36.     int nThreadNum = *(int *)pPM;   
  37.     SetEvent(g_hThread伊夫nt); //触发事件  
  38.       
  39.     Sleep(50);//some work should to do  
  40.       
  41.     EnterCriticalSection(&g_csThreadCode);  
  42.     g_nNum++;  
  43.     Sleep(0);//some work should to do  
  44.     printf(“线程编号为%d  全局财富值为%d\n”, nThreadNum, g_nNum);   
  45.     LeaveCriticalSection(&g_csThreadCode);  
  46.     return 0;  
  47. }  

第四个参数表示安控,一般直接传入NULL。

 LPCTSTRlpName    
//名称

函数原型:

第一个 CreateEvent

 ACCESS 2

秒杀二十四线程第陆篇
二个经典的二十八线程同步难题

1.风浪是内核查象,事件分为手动置位事件自行置位事件。事件伊芙nt内部它含有三个使用计数(全数内核查象都有),三个布尔值表示是手动置位事件照旧机关置位事件,另三个布尔值用来表示事件有无触发。

 DWORDdwDesiredAccess,

对电动置位事件,运转结果如下:

函数成效:依照名称获得叁个风云句柄。

率先介绍下什么样选取事件。事件伊夫nt实际上是个水源对象,它的选择拾分有利。上面列出部分常用的函数。

 

函数原型:BOOLSet伊夫nt(HANDLEh伊夫nt);

在经典二十多线程难题中装置一个轩然大波和3个重要段。用事件处理主线程与子线程的同步,用关键段来处理各子线程间的排挤。详见代码:

 

[cpp] view
plain
copy

函数原型:

先来探视这么些函数的实质:

 LPCTSTRlpName

第五个PulseEvent

明日我们清楚了哪些采用事件,但读书就应该要深深的读书,何况微软给事件还提供了Pulse伊夫nt()函数,所以接下去再持续深挖下事件伊夫nt,看看它还有哪些秘密没。

HANDLECreateEvent(

 

代码如下:

函数表达:

第四个ResetEvent

 

 

       上边对那个触发一个轩然大波脉冲Pulse伊夫nt ()写一个例证,主线程运转八个子线程,在那之中有多少个线程Sleep(10)后对一事变调用等待函数(称为快线程),另有3个线程Sleep(100)后也对该事件调用等待函数(称为慢线程)。主线程运维全体子线程后再Sleep(50)保险有六个快线程都正处在等候状态中。此时若主线程触发一个风云脉冲,那么对于手动置位事件,那三个线程都将顺风实施下去。对于活动置位事件,这个线程中会有中一个顺畅推行下去。而不论是手动置位事件只怕自动置位事件,那3个慢线程由于Sleep(100)所以会错过事件脉冲,因而慢线程都会进入等待状态而一筹莫展如愿实行下去。

函数表明:每便触发后,必有三个或四个处于等候状态下的线程变成可调度意况。

1.对于手动置位事件,全体正处在等候状态下线程都改成可调度情形。

 BOOLbInheritHandle,

首先个参数表示访问权限,对事件一般传入EVENT_ALL_ACCESS。详细表达能够查阅MSDN文档。

第二个 OpenEvent

对手动置位事件,运营结果如下:

函数表明:

其次个参数明确事件是手动置位如故自动置位,传入TRUE表示手动置位,传入FALSE表示自动置位。假如为全自动置位,则对该事件调用WaitForSingleObject()后会自动调用Reset伊夫nt()使事件变成未触及状态。打个细微比方,手动置位事件也正是教室门,图书馆门一旦打开(被触发),所以有人都足以进去直到老师去关上教室门(事件变成未触发)。自动置位事件就一定于医院里拍X光的房间门,门打开后只可以跻身一人,这厮进去后会将门关上,其余人无法进入除非门重新被打开(事件再度被触发)。

 

其多个参数表示事件的起初状态,传入TRUKoleos表示已接触。

函数表明:那是三个不常用的轩然大波函数,此函数相当于Set伊夫nt()后当即调用Reset伊夫nt();此时意况能够分为三种:

 

出于事件是基础对象,因而选用CloseHandle()就足以做到清理与销毁了。

函数原型:BOOLPulse伊芙nt(HANDLEh伊夫nt);

2.事变可以由Set伊芙nt()来触发,由Reset伊夫nt()来设成未接触。还是能够由Pulse伊芙nt()来发生一个轩然大波脉冲。

  1. //使用PluseEvent()函数  
  2. #include <stdio.h>  
  3. #include <conio.h>  
  4. #include <process.h>  
  5. #include <windows.h>  
  6. HANDLE  g_hThreadEvent;  
  7. //快线程  
  8. unsigned int __stdcall FastThreadFun(void *pPM)  
  9. {  
  10.     Sleep(10); //用那一个来确定保证各线程调用等待函数的主次有必然的随机性  
  11.     printf(“%s 启动\n”, (PSTR)pPM);  
  12.     WaitForSingleObject(g_hThreadEvent, INFINITE);  
  13.     printf(“%s 等到事件被触发 顺遂告竣\n”, (PSTR)pPM);  
  14.     return 0;  
  15. }  
  16. //慢线程  
  17. unsigned int __stdcall SlowThreadFun(void *pPM)  
  18. {  
  19.     Sleep(100);  
  20.     printf(“%s 启动\n”, (PSTR)pPM);  
  21.     WaitForSingleObject(g_hThreadEvent, INFINITE);  
  22.     printf(“%s 等到事件被触发 顺遂完工\n”, (PSTR)pPM);  
  23.     return 0;  
  24. }  
  25. int main()  
  26. {  
  27.     printf(”  使用PluseEvent()函数\n”);  
  28.     printf(” — by MoreWindows( http://blog.csdn.net/MoreWindows ) –\n\n”);  
  29.   
  30.     BOOL bManualReset = FALSE;  
  31.     //创建事件 第三个参数手动置位TRUE,自动置位FALSE  
  32.     g_hThreadEvent = CreateEvent(NULL, bManualReset, FALSE, NULL);  
  33.     if (bManualReset == TRUE)  
  34.         printf(“当前应用手动置位事件\n”);  
  35.     else  
  36.         printf(“当前选取机动置位事件\n”);  
  37.   
  38.     char szFastThreadName[5][30] = {“快线程1000”, “快线程1001”, “快线程1002”, “快线程1003”, “快线程1004”};  
  39.     char szSlowThreadName[2][30] = {“慢线程196”, “慢线程197”};  
  40.   
  41.     int i;  
  42.     for (i = 0; i < 5; i++)  
  43.         _beginthreadex(NULL, 0, FastThreadFun, szFastThreadName[i], 0, NULL);  
  44.     for (i = 0; i < 2; i++)  
  45.         _beginthreadex(NULL, 0, SlowThreadFun, szSlowThreadName[i], 0, NULL);  
  46.       
  47.     Sleep(50); //保险快线程已经全体起步  
  48.     printf(“现在主线程触发三个风浪脉冲 – Pulse伊夫nt()\n”);  
  49.     PulseEvent(g_hThread伊芙nt);//调用Pulse伊夫nt()就一定于同时调用上边二句  
  50.     //SetEvent(g_hThreadEvent);  
  51.     //ResetEvent(g_hThreadEvent);  
  52.       
  53.     Sleep(3000);   
  54.     printf(“时间到,主线程停止运维\n”);  
  55.     CloseHandle(g_hThreadEvent);  
  56.     return 0;  
  57. }  

末尾总计下事件伊夫nt

 

ACCESS 3

函数作用:创制事件

第多个参数表示事件的名称,传入NULL表示匿名事件。

 

函数成效:将事件触发后旋即将事件设置为未触及,也就是触发贰个轩然大波脉冲。

自此风云是末触发的。该函数不安静,因为无法预知在调用Pulse伊夫nt
()时怎么线程正处在等候景况。

其四个参数表示名称,不一样进度中的各线程能够通过名称来保障它们访问同三个事变。

第三个SetEvent

3.事件能够化解线程间同步难点,由此也能一蹴而就互斥难点。

秒杀四线程第肆篇
经典线程同步关键段CS》

运作结果如下图:

翻阅本篇在此之前推荐阅读以下姊妹篇:

[cpp] view
plain
copy

);

 BOOLbManualReset,

函数原型:BOOLReset伊夫nt(HANDLEh伊芙nt);

 

函数功效:将事件设为末触发

可以看出来,经典线线程同步难题早已到家的缓解了——线程编号的输出没有再一次,表明主线程与子线程达到了联合。全局财富的出口是多如牛毛的,表明各子线程已经互斥的走访和输出该全局财富。

 BOOLbInitialState,

最后2个事件的清理与销毁

);

相关文章