当前位置: 首页 > news >正文

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

使用事件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 网页操作自动化, 图像分析破解,游戏开发

http://www.lryc.cn/news/64693.html

相关文章:

  • JavaWeb学习------jQuery
  • 米哈游测开岗 【一面总结】
  • 微服务 Spring Boot 整合Redis 实现优惠卷秒杀 一人一单
  • 构建OVS网络
  • 【Python】万能之王 Lambda 函数详解
  • 手把手教你怎么搭建自己的AI数字人直播间?帮你24小时不间断直播卖货
  • MySQL性能监控全掌握,快来get关键指标及采集方法!
  • sed进阶之保留空间和排除命令
  • 21安徽练习
  • 【VAR | 时间序列】应用VAR模型时的15个注意点
  • 校招在线测评题目汇总
  • 『python爬虫』05. requests模块入门(保姆级图文)
  • WPF超好用的框架Prism入门使用,上位机赶紧学起来!
  • 十个机器学习应用实例
  • 【Redis17】Redis进阶:管道
  • Django项目页面样式如何“传给”客户端浏览器
  • python 进程间通信 Queue()、Pipe()、manager.list()、manager.dict()、manager.Queue()
  • 你想要的【微前端】都在这里了! | 京东云技术团队
  • 人生若只如初见,你不来看看Django吗
  • 项目人力资源管理
  • 提供接口给第三方调用,应该注意什么
  • ESL设计概述
  • 探究C语言数组的奥秘:大小可省略的定义、内存存储、数组名、传参、指针遍历、数组指针和指针数组、柔性数组等
  • python3 强制使用任意父级相对导入,越过python相对导入限制,拒绝 ImportError
  • 面了一个4年经验的测试工程师,自动化都不会也要15k,我也是醉了····
  • Java 实现 YoloV7 人体姿态识别
  • 跨越屏幕:桌面PC端的多端开发框架介绍
  • 高效学习方法和工具推荐,让你事半功倍!
  • 查看Docker容器中RabbitMQ的密码
  • 探索Qt线程编程的奥秘:多角度深入剖析