CreateEvent 函數(shù)
函數(shù)功能描述:創(chuàng)建或打開一個命名的或無名的事件對象
函數(shù)原型:
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全屬性
BOOL bManualReset, // 復位方式
BOOL bInitialState, // 初始狀態(tài)
LPCTSTR lpName // 對象名稱
);
參數(shù):
lpEventAttributes:
[輸入]一個指向SECURITY_ATTRIBUTES結(jié)構(gòu)的指針,確定返回的句柄是否可被子進程繼承。如果lpEventAttributes是NULL,此句柄不能被繼承。
Windows NT/2000:lpEventAttributes的結(jié)構(gòu)中的成員為新的事件指定了一個安全符。如果lpEventAttributes是NULL,事件將獲得一個默認的安全符。
bManualReset:
[輸入]指定將事件對象創(chuàng)建成手動復原還是自動復原。如果是TRUE,那么必須用ResetEvent函數(shù)來手工將事件的狀態(tài)復原到無信號狀態(tài)。如果設置為FALSE,當事件被一個等待線程釋放以后,系統(tǒng)將會自動將事件狀態(tài)復原為無信號狀態(tài)。
bInitialState:
[輸入]指定事件對象的初始狀態(tài)。如果為TRUE,初始狀態(tài)為有信號狀態(tài);否則為無信號狀態(tài)。
lpName:
[輸入]指定事件的對象的名稱,是一個以0結(jié)束的字符串指針。名稱的字符格式限定在MAX_PATH之內(nèi)。名字是對大小寫敏感的。
如果lpName指定的名字,與一個存在的命名的事件對象的名稱相同,函數(shù)將請求EVENT_ALL_ACCESS來訪問存在的對象。這時候,由于bManualReset和bInitialState參數(shù)已經(jīng)在創(chuàng)建事件的進程中設置,這兩個參數(shù)將被忽略。如果lpEventAttributes是參數(shù)不是NULL,它將確定此句柄是否可以被繼承,但是其安全描述符成員將被忽略。
如果lpName為NULL,將創(chuàng)建一個無名的事件對象。
如果lpName的和一個存在的信號、互斥、等待計時器、作業(yè)或者是文件映射對象名稱相同,函數(shù)將會失敗,在GetLastError函數(shù)中將返回ERROR_INVALID_HANDLE。造成這種現(xiàn)象的原因是這些對象共享同一個命名空間。
終端服務(Terminal Services):名稱中可以加入"Global\"或是"Local\"的前綴,這樣可以明確的將對象創(chuàng)建在全局的或事務的命名空間。名稱的其它部分除了反斜杠(\),可以使用任意字符。詳細內(nèi)容可參考Kernel Object Name Spaces。
Windows 2000:在Windows 2000系統(tǒng)中,沒有終端服務運行,"Global\"和"Local\"前綴將被忽略。名稱的其它部分除了反斜杠(\),可以使用任意字符。
Windows NT 4.0以及早期版本, Windows 95/98:名稱中除了反斜杠(\),可以使用任意字符。
返回值:
如果函數(shù)調(diào)用成功,函數(shù)返回事件對象的句柄。如果對于命名的對象,在函數(shù)調(diào)用前已經(jīng)被創(chuàng)建,函數(shù)將返回存在的事件對象的句柄,而且在GetLastError函數(shù)中返回ERROR_ALREADY_EXISTS。
如果函數(shù)失敗,函數(shù)返回值為NULL,如果需要獲得詳細的錯誤信息,需要調(diào)用GetLastError。
備注:
調(diào)用CreateEvent函數(shù)返回的句柄,該句柄具有EVENT_ALL_ACCESS權(quán)限去訪問新的事件對象,同時它可以在任何有此事件對象句柄的函數(shù)中使用。
在調(diào)用的過程中,所有線程都可以在一個等待函數(shù)中指定事件對象句柄。當指定的對象的狀態(tài)被置為有信號狀態(tài)時,單對象等待函數(shù)將返回。
對于多對象等待函數(shù),可以指定為任意或所有指定的對象被置為有信號狀態(tài)。當?shù)却瘮?shù)返回時,等待線程將被釋放去繼續(xù)運行。
初始狀態(tài)在bInitialState參數(shù)中進行設置。使用SetEvent函數(shù)將事件對象的狀態(tài)置為有信號狀態(tài)。使用ResetEvent函數(shù)將事件對象的狀態(tài)置為無信號狀態(tài)。
當一個手動復原的事件對象的狀態(tài)被置為有信號狀態(tài)時,該對象狀態(tài)將一直保持有信號狀態(tài),直至明確調(diào)用ResetEvent函數(shù)將其置為無符號狀態(tài)。
當事件的對象被置為有信號狀態(tài)時,任意數(shù)量的等待中線程,以及隨后開始等待的線程均會被釋放。
當一個自動復原的事件對象的狀態(tài)被置為有信號狀態(tài)時,該對象狀態(tài)將一直保持有信號狀態(tài),直至一個等待線程被釋放;系統(tǒng)將自動將此函數(shù)置為無符號狀態(tài)。如果沒有等待線程正在等待,事件對象的狀態(tài)將保持有信號狀態(tài)。
多個進程可持有同一個事件對象的多個句柄,可以通過使用此對象來實現(xiàn)進程間的同步。下面的對象共享機制是可行的:
·在CreateEvent函數(shù)中,lpEventAttributes參數(shù)指定句柄可被繼承時,通過CreateProcess函數(shù)創(chuàng)建的子進程繼承的事件對象句柄。
·一個進程可以在DuplicateHandle函數(shù)中指定事件對象句柄,從而獲得一個復制的句柄,此句柄可以被其它進程使用。
·一個進程可以在OpenEvent或CreateEvent函數(shù)中指定一個名字,從而獲得一個有名的事件對象句柄。
使用CloseHandle函數(shù)關(guān)閉句柄。當進程停止時,系統(tǒng)將自動關(guān)閉句柄。當最后一個句柄被關(guān)閉后,事件對象將被銷毀。
使用環(huán)境:
Windows NT/2000:需要3.1或更高版本
Windows 95/98:需要Windows 95或更高版本
頭文件:定義在Winbase.h;需要包含 Windows.h。
導入庫:user32.lib
Unicode:在Windows NT/2000中,以 Unicode 和 ANSI 執(zhí)行
參考:
Synchronization Overview, Synchronization Functions, CloseHandle, CreateProcess, DuplicateHandle, OpenEvent, ResetEvent, SECURITY_ATTRIBUTES, SetEvent, Object Names
示例代碼:
// 創(chuàng)建一個有名的,不能被繼承的,手動復原,初始狀態(tài)是無信號狀態(tài)的事件對象
Handle h = CreateEvent(NULL,TRUE,FALSE,“MyEvent”);
函數(shù)功能描述:創(chuàng)建或打開一個命名的或無名的事件對象
函數(shù)原型:
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全屬性
BOOL bManualReset, // 復位方式
BOOL bInitialState, // 初始狀態(tài)
LPCTSTR lpName // 對象名稱
);
參數(shù):
lpEventAttributes:
[輸入]一個指向SECURITY_ATTRIBUTES結(jié)構(gòu)的指針,確定返回的句柄是否可被子進程繼承。如果lpEventAttributes是NULL,此句柄不能被繼承。
Windows NT/2000:lpEventAttributes的結(jié)構(gòu)中的成員為新的事件指定了一個安全符。如果lpEventAttributes是NULL,事件將獲得一個默認的安全符。
bManualReset:
[輸入]指定將事件對象創(chuàng)建成手動復原還是自動復原。如果是TRUE,那么必須用ResetEvent函數(shù)來手工將事件的狀態(tài)復原到無信號狀態(tài)。如果設置為FALSE,當事件被一個等待線程釋放以后,系統(tǒng)將會自動將事件狀態(tài)復原為無信號狀態(tài)。
bInitialState:
[輸入]指定事件對象的初始狀態(tài)。如果為TRUE,初始狀態(tài)為有信號狀態(tài);否則為無信號狀態(tài)。
lpName:
[輸入]指定事件的對象的名稱,是一個以0結(jié)束的字符串指針。名稱的字符格式限定在MAX_PATH之內(nèi)。名字是對大小寫敏感的。
如果lpName指定的名字,與一個存在的命名的事件對象的名稱相同,函數(shù)將請求EVENT_ALL_ACCESS來訪問存在的對象。這時候,由于bManualReset和bInitialState參數(shù)已經(jīng)在創(chuàng)建事件的進程中設置,這兩個參數(shù)將被忽略。如果lpEventAttributes是參數(shù)不是NULL,它將確定此句柄是否可以被繼承,但是其安全描述符成員將被忽略。
如果lpName為NULL,將創(chuàng)建一個無名的事件對象。
如果lpName的和一個存在的信號、互斥、等待計時器、作業(yè)或者是文件映射對象名稱相同,函數(shù)將會失敗,在GetLastError函數(shù)中將返回ERROR_INVALID_HANDLE。造成這種現(xiàn)象的原因是這些對象共享同一個命名空間。
終端服務(Terminal Services):名稱中可以加入"Global\"或是"Local\"的前綴,這樣可以明確的將對象創(chuàng)建在全局的或事務的命名空間。名稱的其它部分除了反斜杠(\),可以使用任意字符。詳細內(nèi)容可參考Kernel Object Name Spaces。
Windows 2000:在Windows 2000系統(tǒng)中,沒有終端服務運行,"Global\"和"Local\"前綴將被忽略。名稱的其它部分除了反斜杠(\),可以使用任意字符。
Windows NT 4.0以及早期版本, Windows 95/98:名稱中除了反斜杠(\),可以使用任意字符。
返回值:
如果函數(shù)調(diào)用成功,函數(shù)返回事件對象的句柄。如果對于命名的對象,在函數(shù)調(diào)用前已經(jīng)被創(chuàng)建,函數(shù)將返回存在的事件對象的句柄,而且在GetLastError函數(shù)中返回ERROR_ALREADY_EXISTS。
如果函數(shù)失敗,函數(shù)返回值為NULL,如果需要獲得詳細的錯誤信息,需要調(diào)用GetLastError。
備注:
調(diào)用CreateEvent函數(shù)返回的句柄,該句柄具有EVENT_ALL_ACCESS權(quán)限去訪問新的事件對象,同時它可以在任何有此事件對象句柄的函數(shù)中使用。
在調(diào)用的過程中,所有線程都可以在一個等待函數(shù)中指定事件對象句柄。當指定的對象的狀態(tài)被置為有信號狀態(tài)時,單對象等待函數(shù)將返回。
對于多對象等待函數(shù),可以指定為任意或所有指定的對象被置為有信號狀態(tài)。當?shù)却瘮?shù)返回時,等待線程將被釋放去繼續(xù)運行。
初始狀態(tài)在bInitialState參數(shù)中進行設置。使用SetEvent函數(shù)將事件對象的狀態(tài)置為有信號狀態(tài)。使用ResetEvent函數(shù)將事件對象的狀態(tài)置為無信號狀態(tài)。
當一個手動復原的事件對象的狀態(tài)被置為有信號狀態(tài)時,該對象狀態(tài)將一直保持有信號狀態(tài),直至明確調(diào)用ResetEvent函數(shù)將其置為無符號狀態(tài)。
當事件的對象被置為有信號狀態(tài)時,任意數(shù)量的等待中線程,以及隨后開始等待的線程均會被釋放。
當一個自動復原的事件對象的狀態(tài)被置為有信號狀態(tài)時,該對象狀態(tài)將一直保持有信號狀態(tài),直至一個等待線程被釋放;系統(tǒng)將自動將此函數(shù)置為無符號狀態(tài)。如果沒有等待線程正在等待,事件對象的狀態(tài)將保持有信號狀態(tài)。
多個進程可持有同一個事件對象的多個句柄,可以通過使用此對象來實現(xiàn)進程間的同步。下面的對象共享機制是可行的:
·在CreateEvent函數(shù)中,lpEventAttributes參數(shù)指定句柄可被繼承時,通過CreateProcess函數(shù)創(chuàng)建的子進程繼承的事件對象句柄。
·一個進程可以在DuplicateHandle函數(shù)中指定事件對象句柄,從而獲得一個復制的句柄,此句柄可以被其它進程使用。
·一個進程可以在OpenEvent或CreateEvent函數(shù)中指定一個名字,從而獲得一個有名的事件對象句柄。
使用CloseHandle函數(shù)關(guān)閉句柄。當進程停止時,系統(tǒng)將自動關(guān)閉句柄。當最后一個句柄被關(guān)閉后,事件對象將被銷毀。
使用環(huán)境:
Windows NT/2000:需要3.1或更高版本
Windows 95/98:需要Windows 95或更高版本
頭文件:定義在Winbase.h;需要包含 Windows.h。
導入庫:user32.lib
Unicode:在Windows NT/2000中,以 Unicode 和 ANSI 執(zhí)行
參考:
Synchronization Overview, Synchronization Functions, CloseHandle, CreateProcess, DuplicateHandle, OpenEvent, ResetEvent, SECURITY_ATTRIBUTES, SetEvent, Object Names
示例代碼:
// 創(chuàng)建一個有名的,不能被繼承的,手動復原,初始狀態(tài)是無信號狀態(tài)的事件對象
Handle h = CreateEvent(NULL,TRUE,FALSE,“MyEvent”);