1. 程式人生 > >c++CreateEvent函式在多執行緒中使用及例項

c++CreateEvent函式在多執行緒中使用及例項

CreateEvent函式詳解參見本部落格文章:

HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset, 
BOOL bInitialState,
LPCSTR lpName
);
bManualReset:TRUE,使用ResetEvent()手動重置為無訊號狀態;FALSE,當一個等待執行緒被釋放時,自動重置狀態為無訊號狀態。

bInitialState:指定事件物件的初始狀態,當TRUE,初始狀態為有訊號狀態;當FALSE,初始狀態為無訊號狀態。

下面主要演示一下采用CreateEvent實現多執行緒。

例子很簡單,主要測試CreateEvent中bManualReset:和bInitialState引數的取值線上程呼叫中訊號狀態的情況。

測試1:

bManualReset:TRUE
bInitialState:TRUE

CreateEvent(NULL, TRUE, TRUE, NULL); //使用手動重置為無訊號狀態,初始化時有訊號狀態

example.cpp

  1. #include "iostream"
  2. #include "windows.h"
  3. usingnamespace std;  
  4. DWORD WINAPI ThreadProc1(LPVOID lpParam);  
  5. DWORD WINAPI ThreadProc2(
    LPVOID lpParam);  
  6. HANDLE hEvent = NULL;  
  7. HANDLE hThread1 = NULL;  
  8. HANDLE hThread2 = NULL;  
  9. int main(int argc, char *args[])  
  10. {  
  11.     <span style="color:#ff0000;">hEvent = CreateEvent(NULL, TRUE, TRUE, NULL)</span>; //使用手動重置為無訊號狀態,初始化時有訊號狀態
  12.     //hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); //當一個等待執行緒被釋放時,自動重置為無訊號狀態,初始是有訊號狀態
  13.     //if (SetEvent(hEvent))
  14.     //{
  15.     //  cout << "setEvent 成功" <<endl;
  16.     //}
  17.     hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc1, NULL, 0,NULL);  
  18.     Sleep(200);  
  19.     hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc2, NULL, 0,NULL);  
  20.     Sleep(200);  
  21.     if ( NULL == hThread1)  
  22.     {  
  23.         cout <<"create thread fail!";  
  24.     }  
  25.     //DWORD dCount = ResumeThread(hThread);
  26.     //cout << LOWORD(dCount) << endl;
  27.     return 0;  
  28. }  
  29. DWORD WINAPI ThreadProc1(LPVOID lpParam)  
  30. {  
  31.     cout <<"in [email protected]!"<<endl;  
  32.     DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);  
  33.     if ( WAIT_OBJECT_0 == dReturn)  
  34.     {  
  35.         cout <<" thread1 signaled ! "<<endl;  
  36.     }  
  37.     cout <<"in thread1 --signal"<<endl;  
  38.     //SetEvent(hEvent);
  39.     return 0;  
  40. }  
  41. DWORD WINAPI ThreadProc2(LPVOID lpParam)  
  42. {  
  43.     cout <<"in [email protected]!"<<endl;  
  44.     DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);  
  45.     if ( WAIT_OBJECT_0 == dReturn)  
  46.     {  
  47.         cout <<"thread2 signaled ! "<<endl;  
  48.     }  
  49.     cout <<"in thread2--signal"<<endl;  
  50.     return 0;  
  51. }  

執行結果:


從結果中看,執行完執行緒1又執行了執行緒2.

由於hEvent = CreateEvent(NULL, TRUE, TRUE, NULL),使用手動重置為無訊號狀態,初始化時有訊號狀態

所以hEvent一直處於有訊號狀態,無論是執行緒1釋放後,hEvent仍處於有訊號狀態,所以執行緒2正常執行了。

測試2:

bManualReset:FALSE
bInitialState:TRUE

  1. hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); //當一個等待執行緒被釋放時,自動重置為無訊號狀態,初始是有訊號狀態

example2.cpp

  1. #include "iostream"
  2. #include "windows.h"
  3. usingnamespace std;  
  4. DWORD WINAPI ThreadProc1(LPVOID lpParam);  
  5. DWORD WINAPI ThreadProc2(LPVOID lpParam);  
  6. HANDLE hEvent = NULL;  
  7. HANDLE hThread1 = NULL;  
  8. HANDLE hThread2 = NULL;  
  9. int main(int argc, char *args[])  
  10. {  
  11.     //hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); //使用手動重置為無訊號狀態,初始化時有訊號狀態
  12.     <span style="color:#ff0000;">hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); </span>//當一個等待執行緒被釋放時,自動重置為無訊號狀態,初始是有訊號狀態
  13.     //if (SetEvent(hEvent))
  14.     //{
  15.     //  cout << "setEvent 成功" <<endl;
  16.     //}
  17.     hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc1, NULL, 0,NULL);  
  18.     Sleep(200);  
  19.     hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc2, NULL, 0,NULL);  
  20.     Sleep(200);  
  21.     if ( NULL == hThread1)  
  22.     {  
  23.         cout <<"create thread fail!";  
  24.     }  
  25.     //DWORD dCount = ResumeThread(hThread);
  26.     //cout << LOWORD(dCount) << endl;
  27.     return 0;  
  28. }  
  29. DWORD WINAPI ThreadProc1(LPVOID lpParam)  
  30. {  
  31.     cout <<"in [email protected]!"<<endl;  
  32.     DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);  
  33.     if ( WAIT_OBJECT_0 == dReturn)  
  34.     {  
  35.         cout <<" thread1 signaled ! "<<endl;  
  36.     }  
  37.     cout <<"in thread1 --signal"<<endl;  
  38.     //SetEvent(hEvent);
  39.     return 0;  
  40. }  
  41. DWORD WINAPI ThreadProc2(LPVOID lpParam)  
  42. {  
  43.     cout <<"in [email protected]!"<<endl;  
  44.     DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);  
  45.     if ( WAIT_OBJECT_0 == dReturn)  
  46.     {  
  47.         cout <<"thread2 signaled ! "<<endl;  
  48.     }  
  49.     cout <<"in thread2--signal"<<endl;  
  50.     return 0;  
  51. }  
執行結果:


從執行結果中分析,執行了執行緒1,執行緒2一直在等待,直到主執行緒結束。

由於hEvent = CreateEvent(NULL, FALSE, TRUE, NULL),當一個等待執行緒被釋放時,自動重置為無訊號狀態,初始是有訊號狀態

初始執行執行緒1的時候,hEvent是有訊號的,所以執行緒1正常執行;又由於bManualReset=FALSE,所以執行完執行緒1後,hEvent自動重置為無訊號狀態,所以線上程2中,

  1. WaitForSingleObject(hEvent,INFINITE);  
函式一直在等待hEvent變為有訊號狀態,但是當主執行緒執行完,還沒等待到,執行緒2程式一直沒有走下去。

測試3:

bManualReset:TRUE
bInitialState:FALSE

hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//使用手動重置為無訊號狀態,初始化時為無訊號狀態

example3.cpp

  1. #include "iostream"
  2. #include "windows.h"
  3. usingnamespace std;  
  4. DWORD WINAPI ThreadProc1(LPVOID lpParam);  
  5. DWORD WINAPI ThreadProc2(LPVOID lpParam);  
  6. HANDLE hEvent = NULL;  
  7. HANDLE hThread1 = NULL;  
  8. HANDLE hThread2 = NULL;  
  9. int main(int argc, char *args[])  
  10. {  
  11.     //hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); //使用手動重置為無訊號狀態,初始化時有訊號狀態
  12.     //hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); //當一個等待執行緒被釋放時,自動重置為無訊號狀態,初始是有訊號狀態
  13.     <span style="color:#ff0000;">hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//使用手動重置為無訊號狀態,初始化時為無訊號狀態</span>
  14.     //if (SetEvent(hEvent))
  15.     //{
  16.     //  cout << "setEvent 成功" <<endl;
  17.     //}
  18.     hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc1, NULL, 0,NULL);  
  19.     Sleep(200);  
  20.     hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc2, NULL, 0,NULL);  
  21.     Sleep(200);  
  22.     if ( NULL == hThread1)  
  23.     {  
  24.         cout <<"create thread fail!";  
  25.     }  
  26.     //DWORD dCount = ResumeThread(hThread);
  27.     //cout << LOWORD(dCount) << endl;
  28.     return 0;  
  29. }  
  30. DWORD WINAPI ThreadProc1(LPVOID lpParam)  
  31. {  
  32.     cout <<"in [email protected]!"<<endl;  
  33.     DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);  
  34.     if ( WAIT_OBJECT_0 == dReturn)  
  35.     {  
  36.         cout <<" thread1 signaled ! "<<endl;  
  37.     }  
  38.     cout <<"in thread1 --signal"<<endl;  
  39.     //SetEvent(hEvent);
  40.     return 0;  
  41. }  
  42. DWORD WINAPI ThreadProc2(LPVOID lpParam)  
  43. {  
  44.     cout <<"in [email protected]!"<<endl;  
  45.     DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);  
  46.     if ( WAIT_OBJECT_0 == dReturn)  
  47.     {  
  48.         cout <<"thread2 signaled ! "<<endl;  
  49.     }  
  50.     cout <<"in thread2--signal"<<endl;  
  51.     return 0;  
  52. }  

執行結果,可想而知,只能輸出:
  1. in [email protected]!  
  1. in [email protected]!  
因為初始為無訊號狀態,所以hEvent一直處於無訊號狀態,因此這兩個執行緒一直在等待,直到主執行緒結束。

修改:放開例子中的註釋部分:

if (SetEvent(hEvent))//設定訊號為有訊號狀態
{
cout << "setEvent 成功" <<endl;
}

執行結果:


可見,執行緒1和執行緒2都執行了。

因為呼叫SetEvent,事件變為有訊號狀態,執行緒1執行;又由於執行緒1釋放後,hEvent仍舊處於有訊號狀態,所以執行緒2也執行了。

再修改:線上程1中,新增ResetEvent(hEvent)(手動設定事件為無訊號狀態),則執行緒2不會執行。

測試4:

bManualReset:FALSE
bInitialState:FALSE

hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);//執行緒釋放後自動重置為無訊號狀態,初始化時為無訊號狀態

example4.cpp

  1. #include "iostream"
  2. #include "windows.h"
  3. usingnamespace std;  
  4. DWORD WINAPI ThreadProc1(LPVOID lpParam);  
  5. DWORD WINAPI ThreadProc2(LPVOID lpParam);  
  6. HANDLE hEvent = NULL;  
  7. HANDLE hThread1 = NULL;  
  8. HANDLE hThread2 = NULL;  
  9. int main(int argc, char *args[])  
  10. {  
  11.     //hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); //使用手動重置為無訊號狀態,初始化時有訊號狀態
  12.     //hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); //當一個等待執行緒被釋放時,自動重置為無訊號狀態,初始是有訊號狀態
  13.     //hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//使用手動重置為無訊號狀態,初始化時為無訊號狀態
  14.     hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);//使用手動重置為無訊號狀態,初始化時為無訊號狀態
  15.     if (SetEvent(hEvent))  
  16.     {  
  17.         cout << "setEvent 成功" <<endl;  
  18.     }  
  19.     hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc1, NULL, 0,NULL);  
  20.     Sleep(200);  
  21.     hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc2, NULL, 0,NULL);  
  22.     Sleep(200);  
  23.     if ( NULL == hThread1)  
  24.     {  
  25.         cout <<"create thread fail!";  
  26.     }  
  27.     //DWORD dCount = ResumeThread(hThread);
  28.     //cout << LOWORD(dCount) << endl;
  29.     return 0;  
  30. }  
  31. DWORD WINAPI ThreadProc1(LPVOID lpParam)  
  32. {  
  33.     cout <<"in [email protected]!"<<endl;  
  34.     DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);  
  35.     if ( WAIT_OBJECT_0 == dReturn)  
  36.     {  
  37.         cout <<" thread1 signaled ! "<<endl;  
  38.     }  
  39.     cout <<"in thread1 --signal"<<endl;  
  40.     //SetEvent(hEvent);
  41.     return 0;  
  42. }  
  43. DWORD WINAPI ThreadProc2(LPVOID lpParam)  
  44. {  
  45.     cout <<"in [email protected]!"<<endl;  
  46.     DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);  
  47.     if ( WAIT_OBJECT_0 == dReturn)  
  48.     {  
  49.         cout <<"thread2 signaled ! "<<endl;  
  50.     }  
  51.     cout <<"in thread2--signal"<<endl;  
  52.     return 0;  
  53. }  

執行結果:


由於呼叫SetEvent,hEvent為有訊號狀態,執行緒1正常執行,又由於呼叫完執行緒1後,hEvent自動重置為無訊號狀態,所以執行緒2只能在等待,直到主執行緒退出。

修改:執行緒1中的SetEvent(hEvent);的註釋去掉,再執行,則執行緒1和執行緒2 都會執行。

相關推薦

C# 如何讓 執行每個執行間隔毫秒執行同一個方法

class Program { static int dur = 200; static string tm = ""; static void Main(string[] args) {

java定時器類Timer和執行介紹例項

任務要求: 完成一個java application應用程式,使用定時器程式設計,在實時顯示當前時間,每1秒時鐘內容更新一次。 完成一個java application應用程式,在應用程式主程序中新開一個執行緒,此執行緒進行死迴圈,每1秒被啟用一次,啟用時即在

c++CreateEvent函式執行使用例項

CreateEvent函式詳解參見本部落格文章: HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,BOOL bManualReset, BOOL bInitialState,LPCSTR lpName);bManualReset:TRU

c++11執行Join函式

寫在前面 Join函式作用: Join thread The function returns when the thread execution has completed.//直到執行緒完成函式才返回 This synchronizes the moment t

C/C++開發】執行程式設計的join函式

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # codi

執行的訊號機制--sigwait 函式

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

C++執行的future(期望)

Providers std::promise 和std::future配合使用,給std::future傳遞期望值,下面是最簡單的一個用法: #include <iostream> #include <functional> #include <

JVMTI 的JNI系列函式執行安全除錯技巧

JVMTI 中的JNI系列函式,執行緒安全及除錯技巧 jni functions 在使用 JVMTI 的過程中,有一大系列的函式是在 JVMTI 的文件中 沒有提及的,但在實際使用卻是非常有用的。這就是 jni functions.

Python執行的join函式的使用與含義

wechat:812716131 ------------------------------------------------------ 技術交流群請聯絡上面wechat ----------------------------------------------

Python執行join函式與setDaemon函式使用說明

      在Python多執行緒程式設計的時候,經常需要用到join函式和setDaemon函式。之前對這兩個函式一直理解不是很到位。今天查閱了很多資料,對兩個函式的認識更加的深入一些了。       join([timeout])可以參考Python文件說明。大概意思就

【java基礎】執行匿名內部類和lambda建立方式,執行的兩個面試題

一、可以用匿名類和lambda兩個種方式建立多執行緒。 1.利用匿名內部類建立多執行緒並開啟。 new Thread() {//建立方式1 public void run() { for(int x=0; x<50; x++) { System.out

執行觸發的事件函式在哪個執行執行

轉載於:https://www.cnblogs.com/findumars/p/5289375.html  在多執行緒開發中,如果在多執行緒中訪問主執行緒建立的物件,並觸發了這個物件的事件,將會執行這個事件的處理函式,那麼這個處理函式是在主執行緒中執行還是在觸發事件的執行

C#在執行使用dictionary時的安全問題

問題出現的情景:在計算一個特徵集中所有特徵與一個數據集的所有例項之間的所有組合距離時,採用多執行緒的方法來提高計算速度。如下,CalculateDistanceThread是計算一個特徵與資料集中所有例項的距離,並將其距離加入到tmp_dist_matrix的字典中。

執行同步非同步函式與序列併發佇列的組合情況

在學習GCD多執行緒程式設計時,需要注意的幾個概念,函式,佇列,執行緒。 非同步函式 + 併發佇列 : 開啟多調執行緒,併發執行操作; 非同步函式 + 序列佇列 : 開啟一條執行緒,序列執行操作; 同步函式 + 併發佇列 : 主執行緒,序列執行操作; 同步函式 + 序列佇列

c++11執行的互斥量

寫在前面 在多執行緒程式中互斥量的概念十分重要,要保護執行緒之間的共享資料,互斥量的lock、unlock、try_lock函式,以及類模板lock_guard、unique_lock十分重要 栗子 首先先看一下,沒有再共享資料上做任何保護的程式: #include <iost

C#執行 && 執行lock用法的經典例項

程序(Process)是Windows系統中的一個基本概念,它包含著一個執行程式所需要的資源。一個正在執行的應用程式在作業系統中被視為一個程序,程序可以包括一個或多個執行緒。執行緒是作業系統分配處理器時間的基本單元,在程序中可以有多個執行緒同時執行程式碼。程序之間是相對獨立的

c語言資料結構應用-陣列佇列(無鎖佇列)在執行的使用

一、背景 上篇文章《c語言資料結構實現-陣列佇列/環形佇列》講述了陣列佇列的原理與實現,本文編寫一個雙執行緒進行速度測試 二、相關知識 多執行緒程式設計介面: 1) 建立執行緒 pthread_create 函式 SYNOPSIS #include <

C++使用Windows API CreateMutex函式執行程式設計

C++中也可以使用Windows 系統中對應的API函式進行多執行緒程式設計。使用CreateThread函式建立執行緒,並且可以通過CreateMutex建立一個互斥量實現執行緒間資料的同步: #

執行的訊號機制--sigwait()函式

這個例子演示了:通過在主執行緒中阻塞一些訊號,其它的執行緒會繼承訊號掩碼,然後專門用一個執行緒使用sigwait函式來同步的處理訊號,使其它的執行緒不受到訊號的影響。#include <pthread.h> #include <stdio.h> #include <sys/sig

C#執行訪問winform控制元件

方法一:System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;  不推薦使用這種方式,禁止編譯器對跨執行緒訪問做檢查的方式實現。 方法二:使用delegate和invoke private