CreateEvent进程间同步
??CreateEvent可以创建或是打开一个命名或是未命名的event对象。
HANDLE CreateEvent(
??LPSECURITY_ATTRIBUTES lpEventAttributes, // pointer to security attributes
??BOOL bManualReset, // flag for manual-reset event
??BOOL bInitialState, // flag for initial state
??LPCTSTR lpName // pointer to event-object name
);
??LPSECURITY_ATTRIBUTES结构体用于创建对象的访问控制属性的,为NULL
的话则使用默认的安全描述符,并且对象可被子进程继承。
??bManualReset参数为TRUE
时,被创建对象需要手动调用ResetEvent
函数恢复为__非信号态__(即不可响应);如果为FALSE
,event对象在响应等待线程后自动恢复成非信号态。
??bInitialState参数为TRUE
时,被创建的对象初始状态为__信号态__(可响应);否则为非信号态。
??lpName参数为event对象名,长度不超过MAX_PATH,字符敏感;如果为NULL,则创建未命名对象。
??现在测试一下如何实现进程间同步。
#include "stdio.h"
#include "Windows.h"
int main() {
HANDLE hEvtObj = NULL;
DWORD hRet = NULL;
CHAR objName[] = { "ObjTestEvt_123" };
if (hEvtObj = CreateEventA(
NULL,
TRUE, // 手动重置为非信号态
FALSE, // 初始不可响应
objName))
{
if (ERROR_ALREADY_EXISTS == GetLastError()) { // 事件对象已存在
printf("Event Obj \"%s\" has EXISTED ...\n", objName);
for (int i = 0; i < 10;) { // 响应10次
hRet = WaitForSingleObject(hEvtObj, 300); // 超时时间为0.3秒
if (!hRet) {
printf("\"%s\" is now SIGNALED %d\n", objName, i++); // 信号态
}
else {
if (WAIT_TIMEOUT == hRet)
printf("\"%s\" is now NONSIGNALED\n", objName); // 非信号态
else
printf("Wait Error %#x...\n", GetLastError());
}
Sleep(1000); // 休眠一秒
}
}
else { // 成功创建事件对象
printf("Create Evt Obj \"%s\" Successful\n", objName);
Sleep(1000); // 等待同步进程运行
printf("Set Event \"%s\" To SIGNALED for 4 seconds...\n", objName);
SetEvent(hEvtObj); // 设置为事件对象为信号态
Sleep(4000); // 休眠4s
printf("Reset Event \"%s\" To NONSIGNALED for 4 seconds...\n", objName);
ResetEvent(hEvtObj); // 设置为非信号态
Sleep(4000); // 让事件对象处于非信号态4s
printf("Set Event \"%s\" To SIGNALED...\n", objName);
SetEvent(hEvtObj); //
}
CloseHandle(hEvtObj);
hEvtObj = NULL;
}
else { // 创建失败
printf("CreateEvent Error = %#x", GetLastError());
}
return 0;
}
??除了进程间,线程也可使用这种方式。
??参考:CreateEvent