实战踩坑---MFC---CreateEvent

CreateEvent函数用于创建事件对象,参数包括安全属性、复位方式和初始状态。手动复原事件需通过ResetEvent手动恢复无信号状态,而自动复原事件在释放一个等待线程后自动复原。在进程间同步时,应使用命名事件。注意释放事件句柄时调用CloseHandle。

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

使用事件CreateEvent注意事项

HANDLECreateEvent(

LPSECURITY_ATTRIBUTESlpEventAttributes,// 安全属性

BOOLbManualReset,// 复位方式

BOOLbInitialState,// 初始状态

LPCTSTRlpName // 对象名称

);[1]

参数

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,将创建一个无名的事件对象。

此处踩坑,如果该句柄为全局变量,设置了事件名称,多个进程之间会相互干扰

注意:

1、如果在进程间同步,需要创建具体名称的事件,即参数lpName不能为nil,事件对象的名称一样。

2、手动复原的情况下,先SetEvent发起信号,后面一定要用ResetEvent复原到无信号状态,一一对应。

如果SetEvent后,所有的事件对象都有信号了。当事件的对象被置为有信号状态时,任意数量的等待中线程,以及随后开始等待的线程均会被释放。

var

  FEvent: Cardinal;

FEvent := CreateEvent(nil, TRUE, FALSE, 'syn_recansend');//创建时无信号的事件

SetEvent(FEvent);//发起信号

或者

FEvent := CreateEvent(nil, TRUE, True, 'syn_recansend');//创建时无信号的事件

//手动复原
procedure TForm1.btn5Click(Sender: TObject);
begin
  if WaitForSingleObject(FEvent, INFINITE) = WAIT_OBJECT_0 then  //等于WAIT_OBJECT_0成功返回有信号
  begin

    ReSetEvent(FEvent);//等到信号后置成无信号,以便其他线程等待
    OutputDebugString('写文件等事情,需要同步的代码');
    SetEvent(FEvent);//做完上面的事情后置成有信号的状态,以便其他线程等待到有信号做事情
  end;

end;

  

3、自动复原信号的情况下,SetEvent只会释放当前等待的一个线程;

当一个自动复原的事件对象的状态被置为有信号状态时,该对象状态将一直保持有信号状态,直至一个等待线程被释放;系统将自动将此函数置为无符号状态。如果没有等待线程正在等待,事件对象的状态将保持有信号状态。

var

  FEvent: Cardinal;

FEvent := CreateEvent(nil, False, FALSE, 'syn_recansend');//创建时无信号的事件

SetEvent(FEvent);//发起信号

或者

FEvent := CreateEvent(nil, False, True, 'syn_recansend');//创建时无信号的事件

//自动复原

procedure TForm1.btn5Click(Sender: TObject);

begin  

  if WaitForSingleObject(FEvent, INFINITE) = WAIT_OBJECT_0 then  //等于WAIT_OBJECT_0成功返回信号时,会释自动释放信号 

  begin

    OutputDebugString('写文件等事情,需要同步的代码');

    SetEvent(FEvent);//做完上面的事情后置成有信号的状态,以便其他线程等待到有信号做事情   ;

  end;

//这里不要SetEvent(FEvent);,上面的WaitForSingleObject等待成功时才会自动ResetEvent,所以上面才会有SetEvent。

end;

4、最后释放事件

if FEvent <> 0 then

  CloseHandle(FEvent);

delphi lazarus opengl 网页操作自动化, 图像分析破解,游戏开发

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值