CreatEvent SetEvent ResetEvent

本文详细介绍了Windows操作系统中事件对象的概念及使用方法,包括创建、设置、重置事件对象的API函数,并解释了自动重置与手工重置的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CreatEvent SetEvent ResetEvent   

CreatEvent():创建一个事件对象

SetEvent():把指定事件对象的状态设置为发信号状态

ResetEvent():把指定事件对象的状态设置为不发信号状态

使用机制:

和事件有关的函数有:

HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,

BOOL bManualReset,BOOL bInitialState,   LPTSTRlpName); 

BOOL SetEvent(HANDLE hEvent); 

BOOL PulseEvent(HANDLE hEvent);

 BOOL ResetEvent(HANDLE hEvent);

 HANDLE OpenEvent(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCTSTRlpName); 

 事件对象是最常用的内核模式同步方法。它包含一个使用计数和两个BOOL变量。其中一个BOOL变量指定这个事件对象是自动重置还是手工重置。另一个BOOL变量指定当前事件对象处于有信号状态还是无信号状态。  

函数CreateEvent创建一个事件对象,参数1必须为NULL,参数2指定是否手工重新设置事件对象的状态。如果为FALSE,当等待函数接到信号并返回后此事件对象被自动置为无信号状态。这时等待此事件对象的其它线程就不会被唤醒,因为事件对象已经被置为无信号状态。

如果参数2设置为TRUE,当等待函数接到信号并返回后事件对象不会被自动置于无信号状态,其它等待此事件对象的线程都能够被唤醒。用ResetEvent函数可以手工将事件对象置为无信号状态。相反SetEvent函数将事件对象置为有信号状态。PulseEvent函数将事件对象置为有信号状态,然后立即置为无信号状态,在实际开发中这个函数很少使用。

OpenEvent函数打开已经创建的事件对象,一般用于不同进程内的线程同步。在调用CreateEvent创建一个事件对象时,传递一个名字给参数4,这样在其它进程中的线程就可以调用OpenEvent函数并指定事件对象的名字,来访问这个事件对象。事件一般都用在线程里,当作信号灯。

 

 

 

HANDLE     CreateEvent(

        LPSECURITY_ATTRIBUTES     lpEventAttributes,     //     SD   
        BOOL     bManualReset,                                                 //     reset     type   
        BOOL     bInitialState,                                                      //     initial     state   
        LPCTSTR     lpName                                                       //     object     name   
    );   
    该函数创建一个Event同步对象,如果CreateEvent调用成功的话,会返回新生成的对象的句柄,否则返回NULL。

参数说明:
    lpEventAttributes     一般为NULL   


    bManualReset      创建的Event是自动复位还是人工复位.如果true,人工复位,   一旦该Event被设置为有信号,则它一直会等到ResetEvent()API被调用时才会恢复 为无信号.     如果为false,Event被设置为有信号,则当有一个wait到它的Thread时,  该Event就会自动复位,变成无信号.   如果想在每次调用WaitForSingleObject 后让WINDOWS为您自动地把事件地状态恢复为”无信号”状态,必须把该参数设为FALSE,否则,您必须每次调用ResetEvent函数来清除事件的信号。


    bInitialState             初始状态,true,有信号,false无信号   
    lpName                  事件对象的名称。您在OpenEvent函数中可能使用。

注释:
    一个Event被创建以后,可以用OpenEvent()API来获得它的Handle,用CloseHandle()    来关闭它,用SetEvent()或PulseEvent()来设置它使其有信号,用ResetEvent()       来使其无信号,用WaitForSingleObject()或WaitForMultipleObjects()来等待其变为有信号.   
   
    PulseEvent()是一个比较有意思的使用方法,正如这个API的名字,它使一个Event 对象的状态发生一次脉冲变化,从无信号变成有信号再变成无信号,而整个操作是原子的.   
    对自动复位的Event对象,它仅释放第一个等到该事件的thread(如果有),而对于人工复位的Event对象,它释放所有等待的thread.  
 


这里有两个API函数用来修改事件对象的信号状态:SetEvent和ResetEvent。前者把事件对象设为”有信号”状态,而后者正好相反。
在事件对象生成后,必须调用WaitForSingleObject来让线程进入等待状态,该函数的语法如下:  
WaitForSingleObject proto hObject:DWORD, dwTimeout:DWORD  
hObject -->指向同步对象的指针。事件对象其实是同步对象的一种。
dwTimeout --> 等待同步对象变成”有信号”前等待的时间,以毫秒计。当等待的时间超过该值后无信号同步对象仍处于”无信号”状态,线程不再等待,WaitForSingleObject函数会返回。如果想要线程一直等待,请把该参数设为INFINITE(该值等于0xffffffff)。 

上一页 1... -1-1-1-1-1-1-1... -1下一页
 
 
 

转载于:https://www.cnblogs.com/gudu0723/archive/2012/08/29/2662530.html

`SetEvent` 和 `ResetEvent` 是 Windows API 中用于线程同步的两个功能。它们通常在多线程程序中用来协调不同线程之间的执行顺序或等待条件。 1. **SetEvent**: - 这个函数用于设置事件对象的状态为“已触发”(Signaled)。当调用者拥有这个事件的句柄并且该事件处于未触发状态时,所有等待此事件的线程会被唤醒并继续执行。如果事件已经被其他线程设置过,则忽略这次操作。 - 使用场景:当某个操作完成,需要通知正在等待的线程时,调用 `SetEvent`。 2. **ResetEvent**: - 这个函数用于重置事件对象的状态为“未触发”(Unsignaled),即取消对它的信号。这使得之前被唤醒但还没有处理完事件的线程知道不再需要立即响应了。 - 使用场景:在一个复杂的同步操作结束后,可能需要让那些原本等待的线程重新进入等待状态,这时可以调用 `ResetEvent`。 在 C++ 中,你需要包含 `<windows.h>` 头文件来使用这两个函数,并确保你的程序链接了合适的库(如 `Kernel32.lib` 或 `user32.lib`)以支持这些系统调用。以下是一个简单的示例: ```cpp #include <windows.h> HANDLE event; // 初始化一个事件对象 // 创建/初始化事件 if (event = CreateEvent(NULL, FALSE, FALSE, "MyEvent")) { // 某个操作完成后 if (!SetEvent(event)) { // 处理错误 } } // 当不再需要触发事件时 if (!ResetEvent(event)) { // 处理错误 } CloseHandle(event); // 最后关闭事件 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值