多线程系列之——事件内核对象

2023-11-19

所有内核对象里面事件内核对象是最简单的一个,它包括一个使用计数,还有两个布尔值。一个布尔值用来表示事件是手动重置事件还是自动重置事件,另一个布尔值表示当前是否处于触发状态。

当一个手动重置事件被触发的时候,所有等待该事件的线程都能变成调度状态。而一个自动重置事件被触发的时候,等待该事件的线程里面只有一个会变成调度状态。

创建一个事件的函数原型如下:

HANDLE WINAPI CreateEvent(
  __in_opt  LPSECURITY_ATTRIBUTES lpEventAttributes,
  __in      BOOL bManualReset,
  __in      BOOL bInitialState,
  __in_opt  LPCTSTR lpName
);

第一个参数是安全描述符,设为NULL表示使用默认的安全描述符,并且子进程无法继承返回的句柄。

第二个参数TRUE表示手动重置,FALSE表示自动重置。

第三个参数FALSE表示事件是未触发状态,TRUE表示事件是触发状态。

第四个参数为事件指定一个名字。如果已经存在,如果已经存在,函数则请求事件的EVENT_ALL_ACCESS权限,此时其它参数将被忽略。(程序只运行一个实例就可以使用这个方法,检测到事件已经存在则退出)

SetEvent设置事件为触发状态,ResetEvent设置事件为未触发状态。

句柄一定要关闭,通过CloseHandle。

WaitForSingleOeject和WaitForMultipleObjects对自动重置事件有个副作用,等待成功后会将事件重置为未触发状态。

 

通过两个例子程序来感受下事件的便利。

现在有三个顾客进了烟酒店,分别要了三包不通的香烟,老板去取香烟,这三个顾客就在柜台前等待(等待事件),老板取来了香烟(事件变成触发状态),付账、拿烟、离开。

第一个例子程序使用手动重置事件,事件出发后,三个顾客可以同时离开。

#include <windows.h>
#include <iostream>

using namespace std;

HANDLE hEvent;//全局事件

DWORD WINAPI CustomerOne(LPVOID lp)
{
	cout << "顾客1:老板,拿包8mg的红双喜" << endl;
	WaitForSingleObject(hEvent,INFINITE);
	cout << "顾客1:这种红双喜非常清爽,谢谢。" << endl;

	return 0;
}

DWORD WINAPI CustomerTwo(LPVOID lp)
{
	cout << "顾客2:14块的利群" << endl;
	WaitForSingleObject(hEvent,INFINITE);
	cout << "顾客2:我喜欢这个香烟,谢谢老板。" << endl;

	return 0;
}

DWORD WINAPI CustomerThree(LPVOID lp)
{
	cout << "顾客3:我要包8mg的中南海" << endl;
	WaitForSingleObject(hEvent,INFINITE);
	cout << "顾客3:一般人抽不惯这个,不过我一直都抽这个。" << endl;

	return 0;
}

int main(int argc, char *argv[])
{
	hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
	HANDLE hThread[3];
	hThread[0] = CreateThread(NULL,0,CustomerOne,0,0,NULL);
	hThread[1] = CreateThread(NULL,0,CustomerTwo,0,0,NULL);
	hThread[2] = CreateThread(NULL,0,CustomerThree,0,0,NULL);

	Sleep(1000);
	cout << "老板:你们要的香烟。" << endl;
	SetEvent(hEvent);

	WaitForMultipleObjects(3,hThread,TRUE,INFINITE);
	cout << endl << "所有线程都退出" << endl;

	CloseHandle(hEvent);
	for(int i = 0;i < 3;++i)
		CloseHandle(hThread[i]);

	return 0;
}


第二个例子使用自动重置事件,三个顾客分别先后离开。(等待成功的副作用,所以三个线程不能同时执行。每个线程等待成功后必须重置事件为触发状态,这样另外的线程就有机会得到执行。)

#include <windows.h>
#include <iostream>

using namespace std;

HANDLE hEvent;//全局事件

DWORD WINAPI CustomerOne(LPVOID lp)
{
	cout << "顾客1:老板,拿包8mg的红双喜" << endl;
	WaitForSingleObject(hEvent,INFINITE);
	cout << "顾客1:这种红双喜非常清爽,谢谢。" << endl;
	SetEvent(hEvent);
	cout << "顾客1离开。" << endl;

	return 0;
}

DWORD WINAPI CustomerTwo(LPVOID lp)
{
	cout << "顾客2:14块的利群" << endl;
	WaitForSingleObject(hEvent,INFINITE);
	cout << "顾客2:我喜欢这个香烟,谢谢老板。" << endl;
	SetEvent(hEvent);
	cout << "顾客2离开。" << endl;

	return 0;
}

DWORD WINAPI CustomerThree(LPVOID lp)
{
	cout << "顾客3:我要包8mg的中南海" << endl;
	WaitForSingleObject(hEvent,INFINITE);
	cout << "顾客3:一般人抽不惯这个,不过我一直都抽这个。" << endl;
	SetEvent(hEvent);
	cout << "顾客3离开。" << endl;

	return 0;
}

int main(int argc, char *argv[])
{
	hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
	HANDLE hThread[3];
	hThread[0] = CreateThread(NULL,0,CustomerOne,0,0,NULL);
	hThread[1] = CreateThread(NULL,0,CustomerTwo,0,0,NULL);
	hThread[2] = CreateThread(NULL,0,CustomerThree,0,0,NULL);

	Sleep(1000);
	cout << "老板:你们要的香烟。" << endl;
	SetEvent(hEvent);

	WaitForMultipleObjects(3,hThread,TRUE,INFINITE);
	cout << endl << "所有线程都退出" << endl;

	CloseHandle(hEvent);
	for(int i = 0;i < 3;++i)
		CloseHandle(hThread[i]);

	return 0;
}



转载自:http://blog.csdn.net/tornodo/article/details/7583136

非常感谢海盗,受益匪浅!


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多线程系列之——事件内核对象 的相关文章

  • TCP/UDP

    TCP与UDP的相关知识 TCP的三次握手具体发生在哪个函数中 补充知识 TCP的三次握手具体发生在哪个函数中 在Linux编程中 在进行TCP网络编程时 通常分为客户端和服务器端两个模块 客户端 fd socket 利用socket生成文
  • jvm原理--简单的程序加载分析

    package com bzu csh 类加载器加载 class文件 gt 初始化static声明 并不赋值 gt 调用类 gt static声明赋值由上到下 程序开始运行 首先执行main方法 执行main方法第一条语句 调用Single

随机推荐

  • 时序预测

    时序预测 MATLAB实现SARIMA时间序列预测 arima函数 经常还会遇到一种情况 即某些时间序列中存在明显的周期性变化 这种周期是由于季节性变化 季度 月度等 引起的 ARIMA的扩展支持SARIMA 它支持对该系列的季节性成分进行
  • 以太坊区块链学习之在私链上部署合约

    上一篇博客介绍了如何搭建私链并在私链上创建账户 挖矿 查看余额 本篇将介绍在私链上部署合约并与之交互 本篇开发环境为MacOS 10 12 建议读者使用macOS系统或者Ubuntu系统 第一步 进入geth客户端 启动私链 进入geth客
  • 网络基础-应用层协议-HTTP/HTTPS

    HTTP HTTPS HTTP 基本概念 协议格式 请求报文 请求方法 请求资源地址 协议版本 应答报文 常见Header 常见状态码与状态描述 Cookie Session http协议特点 HTTPS 基本概念 对称加密与非对称加密 数
  • magic-api简单例子

    1 magic api magic api 是一个基于Java的接口快速开发框架 通过magic api提供的UI界面完成编写接口 无需定义Controller Service Dao Mapper XML VO等Java对象即可完成常见的
  • 继承、重写、重载、 abstract 抽象、 final、向上(向下)转型、多态

    继承 父类 公共的属性和方法 子类 特有的属性和方法 重写 override 1 继承 2 子类拥有和父类的一样的方法 方法名相同 参数列表相同 返回值类型可以缩小 访问控制权限可以方法 可声明的异常 重载 overload 1个类中 方法
  • [LeetCode-01]-Two Sum(求和)

    文章目录 题目相关 Solution 1 暴力求解 2 暴力求解方法改进 3 不可行的方案 后记 每周完成一个ARTS Algorithm Review Tip Share ARTS Algorithm 每周至少做一个 leetcode 的
  • OpenLooKeng连接hive出现UnknownHostException

    背景 最近在验证一个计算的方案 使用的是华为开源的数据虚拟化引擎OpenLookeng hetu 底层基于presto引擎来提供交互式查询分析能力 先前成功部署过一套 添加hive mysql等数据源一切正常 后重新在其他环境进行部署时 连
  • 老胡的周刊(第106期)

    老胡的信息周刊 1 记录这周我看到的有价值的信息 主要针对计算机领域 内容主题极大程度被我个人喜好主导 这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享 项目 quivr 2 Quivr 是您在云中的第二个大脑 让您轻松存储和检
  • windows10-cuda10.1-cudnn7-tensorflow1.4.0配置流程

    1 下载cuda版本 cuda 10 1 105 win10 network exe 并按照流程安装 安装完后 打开cmd 输入 nvcc V 回车查看是否有版本信息 若出现版本信息 则证明nvcc安装成功 2 下载cudnn版本 cudn
  • oracle批量绑定 forall bulk collect用法以及测试案例

    一 如何使用批挷定提高性能 How Do Bulk Binds Improve Performance 在PL SQL 和SQL引擎 engines 中 太多的上下文切换 context switches 会影响性能 这个会发生在当一个循环
  • 黑丝YYDS,通过五十行代码分分钟下载上万张黑丝小姐姐纯欲高清图!(宅男福利)

    前言 夏天已经接近尾声了 虽然各种大白腿会少了很多 但是会冒出很多各种黑色的大长腿哇 尤其是黑色的 黑丝才是永远滴神 今天带你们大饱眼福一波 一 技术路线 requests 网页请求 BeautifulSoup 解析html网页 re 正则
  • c3p0 mysql 自动重连_关于C3P0容错和自动重连特性的研究

    转载 http blog csdn net cutesource article details 5422093 最近常有数据库和网络设备升级和搬迁等事情 而各个应用都是基于数据库连接池做的 大部分都是基于C3P0 数据库或网络状况的变动都
  • FreeBSD开启SSH远程登录

    1 安装时选择上 SSH 或者源码安装 SSH 2 使用 root 登陆系统 3 使用 ee 编辑器编辑 ee etc inetd conf 去掉 ssh 前的 按 ctrl c 再输入 exit 保存退出 4 编辑 ee etc rc c
  • unity零基础学习

    提示 本人作为萌新记录unity学习路线 后期会根据学习情况不断进行修改 自学途径主要依赖siki学院 前言 伴随游戏行业的兴起 unity引擎的使用越来越普遍 本文章主要记录博主本人入门unity的相关记录大部分依赖siki学院进行整理
  • 【入门指南】从Python入门人工智能指南

    作为一个学习者 什么样的学习方式 学习路径能够帮助我们更高效 便捷的入门人工智能 不至于错过奔驰而过的 AI 号列车 人工智能时代持续发展 成为新一轮产业变革的核心驱动力和引领未来发展的战略技术 不仅受到政策的支持 国内人工智能市场规模也在
  • 在VS Code中使用Kotlin

    在VS Code中使用Kotlin 当前Google有意用Kotlin来替代Java 今后在Android开发中 可能Kotlin会成为标准语言 Kotlin语言是由JetBrains公司开发的 就是做IntelliJ IDEA的那家公司
  • Python示例,它演示了如何使用Python中的类和继承来创建一个简单的形状类层次结构:

    定义一个形状类 class Shape def area self pass 定义一个矩形类 继承自形状类 class Rectangle Shape def init self width height self width width
  • Pycharm 安装插件

    Pycharm 安装插件 Pycharm 安装插件 Pycharm 中一些值得安装的插件 Rainbow Brackets IdeaVim Markdown Navigator Translation 如果说编辑器是程序员的武器 那么插件就
  • Notion笔记搭建博客网站 - NotionNext

    NotionNext是什么 NotionNext是我在Github上开源的基于Next js框架开发的博客生成器 目的是帮助写作爱好者们通过Notion笔记快速搭建一个独立站 从而专注于写作 而不需要操心网站的维护 它将您的Notion笔记
  • 多线程系列之——事件内核对象

    所有内核对象里面事件内核对象是最简单的一个 它包括一个使用计数 还有两个布尔值 一个布尔值用来表示事件是手动重置事件还是自动重置事件 另一个布尔值表示当前是否处于触发状态 当一个手动重置事件被触发的时候 所有等待该事件的线程都能变成调度状态