CreateEvent

CreateEvent

CreateEvent是一個Windows API函式。它用來創建或打開一個命名的或無名的事件對象。如果想為對象指定一個訪問掩碼,應當使用CreateEventEx函式。

基本介紹

  • 外文名:CreateEvent
  • 屬於Windows API函式
  • 作用:創建或打開一個命名的事件對象
  • 運行環境:Windows
語法,參數,返回值,備註,示例,使用環境,

語法

HANDLECreateEvent(
LPSECURITY_ATTRIBUTESlpEventAttributes,// 安全屬性
BOOLbManualReset,// 復位方式
BOOLbInitialState,// 初始狀態
LPCTSTRlpName // 對象名稱
);

參數

lpEventAttributes[輸入]
一個指向SECURITY_ATTRIBUTES結構的指針,確定返回的句柄是否可被子進程繼承。如果lpEventAttributes是NULL,此句柄不能被繼承。
Windows NT/2000:lpEventAttributes的結構中的成員為新的事件指定了一個安全符。如果lpEventAttributes是NULL,事件將獲得一個默認的安全符。
bManualReset[輸入]
指定將事件對象創建成手動復原還是自動復原。如果是TRUE,那么必須用ResetEvent函式來手工將事件的狀態復原到無信號狀態。如果設定為FALSE,當一個等待執行緒被釋放以後,系統將會自動將事件狀態復原為無信號狀態。
bInitialState[輸入]
指定事件對象的初始狀態。如果為TRUE,初始狀態為有信號狀態;否則為無信號狀態。
lpName[輸入]
指定事件的對象的名稱,是一個以0結束的字元串指針。名稱的字元格式限定在MAX_PATH之內。名字是對大小寫敏感的。
如果lpName指定的名字,與一個存在的命名的事件對象的名稱相同,函式將請求EVENT_ALL_ACCESS來訪問存在的對象。這時候,由於bManualReset和bInitialState參數已經在創建事件的進程中設定,這兩個參數將被忽略。如果lpEventAttributes是參數不是NULL,它將確定此句柄是否可以被繼承,但是其安全描述符成員將被忽略。
如果lpName為NULL,將創建一個無名的事件對象。
如果lpName的和一個存在的信號、互斥、等待計時器、作業或者是檔案映射對象名稱相同,函式將會失敗,在GetLastError函式中將返回ERROR_INVALID_HANDLE。造成這種現象的原因是這些對象共享同一個命名空間。
終端服務(Terminal Services):名稱中可以加入"Global\"或是"Local\"的前綴,這樣可以明確的將對象創建在全局的或事務的命名空間。名稱的其它部分除了反斜槓(\),可以使用任意字元。詳細內容可參考Kernel Object Name Spaces。
Windows 2000:在Windows 2000系統中,沒有終端服務運行,"Global\"和"Local\"前綴將被忽略。名稱的其它部分除了反斜槓(\),可以使用任意字元。
Windows NT 4.0以及早期版本,Windows 95/98:名稱中除了反斜槓(\),可以使用任意字元。

返回值

如果函式調用成功,函式返回事件對象的句柄。如果對於命名的對象,在函式調用前已經被創建,函式將返回存在的事件對象的句柄,而且在GetLastError函式中返回ERROR_ALREADY_EXISTS。
如果函式失敗,函式返回值為NULL,如果需要獲得詳細的錯誤信息,需要調用GetLastError。

備註

調用CreateEvent函式返回的句柄,該句柄具有EVENT_ALL_ACCESS許可權去訪問新的事件對象,同時它可以在任何有此事件對象句柄的函式中使用。
在調用的過程中,所有執行緒都可以在一個等待函式中指定事件對象句柄。當指定的對象的狀態被置為有信號狀態時,單對象等待函式將返回。
對於多對象等待函式,可以指定為任意或所有指定的對象被置為有信號狀態。當等待函式返回時,等待執行緒將被釋放去繼續運行。
初始狀態在bInitialState參數中進行設定。使用SetEvent函式將事件對象的狀態置為有信號狀態。使用ResetEvent函式將事件對象的狀態置為無信號狀態。
當一個手動復原的事件對象的狀態被置為有信號狀態時,該對象狀態將一直保持有信號狀態,直至明確調用ResetEvent函式將其置為無符號狀態。
當事件的對象被置為有信號狀態時,任意數量的等待中執行緒,以及隨後開始等待的執行緒均會被釋放。
當一個自動復原的事件對象的狀態被置為有信號狀態時,該對象狀態將一直保持有信號狀態,直至一個等待執行緒被釋放;系統將自動將此函式置為無符號狀態。如果沒有等待執行緒正在等待,事件對象的狀態將保持有信號狀態。
多個進程可持有同一個事件對象的多個句柄,可以通過使用此對象來實現進程間的同步。下面的對象共享機制是可行的:
  • 在CreateEvent函式中,lpEventAttributes參數指定句柄可被繼承時,通過CreateProcess函式創建的子進程繼承的事件對象句柄。
  • 一個進程可以在DuplicateHandle函式中指定事件對象句柄,從而獲得一個複製的句柄,此句柄可以被其它進程使用。
  • 一個進程可以在OpenEvent或CreateEvent函式中指定一個名字,從而獲得一個有名的事件對象句柄。
使用CloseHandle函式關閉句柄。當進程停止時,系統將自動關閉句柄。當最後一個句柄被關閉後,事件對象將被銷毀。

示例

// CreatEventDemo.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "iostream"
#include "windows.h"
using namespace std;
DWORD WINAPI ThreadProc1(LPVOID lpParam);
DWORD WINAPI ThreadProc2(LPVOID lpParam);
HANDLE hEvent = NULL;
HANDLE hThread1 = NULL;
HANDLE hThread2 = NULL;
int main(int argc,char *args[])
{
hEvent = CreateEvent(NULL,TRUE,TRUE,NULL); //使用手動重置為無信號狀態,初始化時有信號狀態
hThread1 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProc1,NULL,0,NULL);
Sleep(200);
hThread2 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProc2,NULL,0,NULL);
Sleep(200);
if (NULL == hThread1 || NULL == hThread2)
{
cout <<"create thread fail!";
}
//DWORD dCount = ResumeThread(hThread);
return 0;
}
DWORD WINAPI ThreadProc1(LPVOID lpParam)
{
cout <<"in thread1@!"<<endl;
DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);
if (WAIT_OBJECT_0 == dReturn)
{
cout <<" thread1 signaled ! "<<endl;
}
cout <<"in thread1 --signal"<<endl;
//SetEvent(hEvent);
return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpParam)
{
cout <<"in thread2@!"<<endl;
DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);
if (WAIT_OBJECT_0 == dReturn)
{
cout <<"thread2 signaled ! "<<endl;
}
cout <<"in thread2--signal"<<endl;
return 0;
}

使用環境

客戶端
需要Windows XP、Windows 2000 Professional、Windows NT Workstation、Windows Me、Windows 98或者Windows 95。
伺服器
需要Windows Server 2003、Windows 2000 Server或Windows NT Server。
頭檔案
在Winbase.h中聲明,包含於Windows.h。
庫檔案
Kernel32.lib
DLL
需要Kernel32.dll。
Unicode
CreateEventW(Unicode) 和CreateEventA(ANSI)的形式實現。
一個Event被創建以後,可以用OpenEvent()API來獲得它的Handle,用CloseHandle()來關閉它,用SetEvent()或PulseEvent()來設定它使其有信號,用ResetEvent()來使其無信號,用WaitForSingleObject()或WaitForMultipleObjects()來等待其變為有信號.
PulseEvent()是一個比較有意思的使用方法,正如這個API的名字,它使一個Event對象的狀態發生一次脈衝變化,從無信號變成有信號再變成無信號,而整個操作是原子的.對自動復位的Event對象,它僅釋放第一個等到該事件的thread(如果有),而對於人工復位的Event對象,它釋放所有等待的thread.

相關詞條

熱門詞條

聯絡我們