多线程(五)多线程同步_Event事件
事件和互斥体同样属于内核同步对象,它和互斥体以及临界区在功能上有以下区别
前面的互斥体和临界区主要作用在于确保控制多个线程之间对共享资源访问,保证共享资源的完整性
事件主要作用是通知其它线程一个操作己经完成,可以接下来执行后面剩余操作了,确保多个线程之间的动作以指定的次序发生
例如:一个线程A用于初始化,一个线程B等待线程A初始化后执行后续操作。
当线程A初始化完成后设置线程B等待的事件为己通知状态,此时线程B从等待函数中得到事件己通知状态,就可以知道线程A己经执行完初始化操作,线程B开始执行后续操作
包含三个部份:
使用计数器: 所有内核对象都有这个属性
事件重置类型: 人工重置为TRUE,自动重置为FALSE
通知状态: 通知状态为TRUE,未通知状态为FALSE
注意:事件有一些特殊的地方,根据创建事件时使用自动重置还是人工重置,程序行为就有很大的差别
事件是人工重置时当得到通知,等待该事件的所有线程均变为可调度线程。而事件是自动重置时得到通知,等待该事件的线程中只有一个线程变为可调度线程
创建事件对象
HANDLE CreateEvent(PSECURITY_ATTRIBUTES psa, BOOL fManualReset, BOOL fInitialState, PCTSTR pszName);
1.psa 指向安全属性指针,一般为NULL
2.fManualReset 事件重置类型,人工重置为TRUE,自动重置为FALSE
3.fInitialState 初始化事件状态,通常为FALSE未通知状态
4.pszName 指定事件对象的名称
返回值:
成功返回新事件对象句柄,失败返回0
注意:如果己经有同名的事件对象存在,函数将返回己有的事件对象句柄,不会再创建新的事件对象
设置事件为己通知状态
BOOL SetEvent(HANDLE hEvent);
设置事件为己通知状态
BOOL ResetEvent(HANDLE hEvent);
编写一个Demo用于演示Event事件基本操作
功能介绍:
程序启动时创建三个线程,线程A B C. 先执行线程A,然后执行线程B,然后执行线程C
线程A执行初始化操作,给全局数组赋值大写字母A-E,然后通知线程B,线程B再把全局数组中所有字母改为小写a-e, 然后通知线C,线程C最后把全局数组中所有字母倒置
开始编写代码:
1. 创建个基于对话框的工程EventDemo
2. 添加一个编辑框用于显示信息,修改ID为IDC_EDIT_SHOWINFO, 修改属性为不可读.
3. 定义相关全局变量和线程函数前置声明
char g_szData[] = {};
CEdit* g_pEdit;
HANDLE g_eventInit; //初始化事件
HANDLE g_eventBigToSmall; //大写转小写事件
HANDLE g_eventReverse; //倒置事件
//线程函数前置声明
DWORD WINAPI Thread_Init(LPVOID lpParam);
DWORD WINAPI Thread_BigToSmall(LPVOID lpParam);
DWORD WINAPI Thread_Reverse(LPVOID lpParam);
全局变量和线程函数前置声明
4. OnInitDialog中添加相应代码
BOOL CEventDemoDlg::OnInitDialog()
{
CDialogEx::OnInitDialog(); // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标 //创建三个事件
g_eventInit = CreateEvent(NULL,FALSE,FALSE,NULL);
g_eventBigToSmall = CreateEvent(NULL,FALSE,FALSE,NULL);
g_eventReverse = CreateEvent(NULL,FALSE,FALSE,NULL);
//保存下编辑框指针供线程内部使用
g_pEdit = (CEdit*)GetDlgItem(IDC_EDIT_SHOWINFO);
//创建三个线程
CloseHandle(CreateThread(NULL,,Thread_Init,NULL,,NULL));
CloseHandle(CreateThread(NULL,,Thread_BigToSmall,NULL,,NULL));
CloseHandle(CreateThread(NULL,,Thread_Reverse,NULL,,NULL)); //设置第一件事件为通知状态
SetEvent(g_eventInit); return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
OnInitDialog
5.三个线程代码
DWORD WINAPI Thread_Init(LPVOID lpParam)
{
WaitForSingleObject(g_eventInit,INFINITE);
//赋值五个大写字母A-E
g_szData[] = 'A';
g_szData[] = 'B';
g_szData[] = 'C';
g_szData[] = 'D';
g_szData[] = 'E';
//编辑框输出下相关信息
CString str;
g_pEdit->GetWindowText(str);
str += _T("线程_初始化:");
for (int i=; i<sizeof(g_szData); i++)
{
str += g_szData[i];
}
str += _T("\r\n");
g_pEdit->SetWindowText(str);
//设置为未通知状态
ResetEvent(g_eventInit);
//设置大写转小写事件为通知状态
SetEvent(g_eventBigToSmall);
return TRUE;
}
线程_初始化
DWORD WINAPI Thread_BigToSmall(LPVOID lpParam)
{
WaitForSingleObject(g_eventBigToSmall,INFINITE);
//大写转小写
for (int i = ; i<sizeof(g_szData); i++)
{
g_szData[i] = g_szData[i] + ;
}
//编辑框输出下相关信息
CString str;
g_pEdit->GetWindowText(str);
str += _T("线程_大写转小写:");
for (int i=; i<sizeof(g_szData); i++)
{
str += g_szData[i];
}
str += _T("\r\n");
g_pEdit->SetWindowText(str);
//设置为未通知状态
ResetEvent(g_eventBigToSmall);
//设置倒置事件为通知状态
SetEvent(g_eventReverse);
return TRUE;
}
线程_大写转小写
DWORD WINAPI Thread_Reverse(LPVOID lpParam)
{
WaitForSingleObject(g_eventReverse,INFINITE);
//倒置
int i = ;
int j = sizeof(g_szData) - ;
int temp = ;
for (;i<j;i++,j--)
{
temp = g_szData[i];
g_szData[i] = g_szData[j];
g_szData[j] = temp;
}
//编辑框输出下相关信息
CString str;
g_pEdit->GetWindowText(str);
str += _T("线程_倒置:");
for (i=; i<sizeof(g_szData); i++)
{
str += g_szData[i];
}
str += _T("\r\n");
str += _T("程序执行完毕\r\n");
g_pEdit->SetWindowText(str);
//设置为未通知状态
ResetEvent(g_eventReverse);
return TRUE;
}
线程_倒置
6.DestroyWindow添加相应代码
BOOL CEventDemoDlg::DestroyWindow()
{
CloseHandle(g_eventInit);
CloseHandle(g_eventBigToSmall);
CloseHandle(g_eventReverse); return CDialogEx::DestroyWindow();
}
DestroyWindow
最终演示效果如下:

多线程(五)多线程同步_Event事件的更多相关文章
- {python--GIL锁}一 介绍 二 GIL介绍 三 GIL与Lock 四 GIL与多线程 五 多线程性能测试
python--GIL锁 GIL锁 本节目录 一 介绍 二 GIL介绍 三 GIL与Lock 四 GIL与多线程 五 多线程性能测试 一 背景知识 ''' 定义: In CPython, the gl ...
- php Pthread 多线程 (五) 线程同步
有些时候我们不希望线程调用start()后就立刻执行,在处理完我们的业务逻辑后在需要的时候让线程执行. <?php class Sync extends Thread { private $na ...
- C#多线程之线程同步篇2
在上一篇C#多线程之线程同步篇1中,我们主要学习了执行基本的原子操作.使用Mutex构造以及SemaphoreSlim构造,在这一篇中我们主要学习如何使用AutoResetEvent构造.Manual ...
- Linux多线程编程——多线程与线程同步
多线程 使用多线程好处: 一.通过为每种事件类型的处理单独分配线程,可以简化处理异步事件的代码,线程处理事件可以采用同步编程模式,启闭异步编程模式简单 二.方便的通信和数据交换 由于进程之间具有独立的 ...
- C#简单多线程使用(同步和优先权)
题目: 麦当劳有两个做汉堡的厨师(工号:11,12)和三个销售人员(工号:21,22,23). 厨师生产汉堡,并负责将做好的汉堡放入货架,货架台大小有限,最多放6个汉堡,11和12不能同时往货架台上放 ...
- 多线程(五) java的线程锁
在多线程中,每个线程的执行顺序,是无法预测不可控制的,那么在对数据进行读写的时候便存在由于读写顺序多乱而造成数据混乱错误的可能性.那么如何控制,每个线程对于数据的读写顺序呢?这里就涉及到线程锁. 什么 ...
- python 多进程/多线程/协程 同步异步
这篇主要是对概念的理解: 1.异步和多线程区别:二者不是一个同等关系,异步是最终目的,多线程只是我们实现异步的一种手段.异步是当一个调用请求发送给被调用者,而调用者不用等待其结果的返回而可以做其它的事 ...
- C# 多线程之线程同步
多线程间应尽量避免同步问题,最好不要线程间共享数据.如果必须要共享数据,就需要使用同步技术,确保一次只有一个线程访问和改变共享状态. 一::lock语句 lock语句事设置锁定和接触锁定的一种简单方法 ...
- MFC——9.多线程与线程同步
Lesson9:多线程与线程同步 程序.进程和线程是操作系统的重点,在计算机编程中.多线程技术是提高程序性能的重要手段. 本文主要解说操作系统中程序.进程和线程之间的关系,并通过相互排斥对象和事件对象 ...
随机推荐
- layer icon样式及 一些弹框使用方法
一.layer的icon样式 以上样式测试代码: layer.confirm('icon测试', {icon: 1, title:'提示'}, function(index){ //do someth ...
- ARC082E ConvexScore(神奇思路)
这题就是拼拼凑凑就出来了. 可能看英文题面容易题意杀(小写大写 \(n,N\)),这里复述一遍:对于每个构成凸多边形的点集(每个点恰好都是凸多边形的顶点,必须是严格的凸多边形,内角严格小于 180 度 ...
- [分布式学习]消息队列之rocketmq笔记
文档地址 RocketMQ架构 哔哩哔哩上的视频 mq有很多,近期买了<分布式消息中间件实践>这本书,学习关于mq的相关知识.mq大致有有4个功能: 异步处理.比如业务端需要给用户发送邮件 ...
- 解决node fs.writeFile 生成csv 文件乱码问题
解决node fs.writeFile 生成csv 文件乱码问题: fs.writeFile('xxx.csv', '\ufeff' + 要传入的数据, {encoding: 'utf8'}); \u ...
- win7 下docker 镜像加速
打开 Kitematic 运行 docker cli 注册镜像 https://www.daocloud.io/mirror#accelerator-doc 上有镜像地址 sudo sed -i &q ...
- 【转载】什么是NVMe?
什么是NVMe? [转载]什么是NVMe:http://storage.it168.com/a2018/0921/5045/000005045252.shtml NVMe是Non-Volatile M ...
- kali渗透综合靶机(十八)--FourAndSix2靶机
kali渗透综合靶机(十八)--FourAndSix2靶机 靶机下载地址:https://download.vulnhub.com/fourandsix/FourAndSix2.ova 一.主机发现 ...
- Enum.GetValues(),返回System.Array的一个实例
Array enumData = Enum.GetValues(e.GetType()); Console.WriteLine("This enum has {0} members.&quo ...
- jenkins安装后提示localhost 拒绝了我们的连接请求。
我是用msi文件安装的windows本地 ,安装文件看另外安装的博文. 此问题解决不是第一次安装方案 ,而是第一次安装完,使用也正常,关电脑再次访问的时候提示找不到 ,是因为本地服务没有启动 ,wi ...
- LeetCode——Department Highest Salary(花式使用IN以及GROUP BY)
The Employee table holds all employees. Every employee has an Id, a salary, and there is also a colu ...