多线程(五)多线程同步_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:多线程与线程同步 程序.进程和线程是操作系统的重点,在计算机编程中.多线程技术是提高程序性能的重要手段. 本文主要解说操作系统中程序.进程和线程之间的关系,并通过相互排斥对象和事件对象 ...
随机推荐
- docker 通过中间镜像加速部署
概要 实施 修改前的实施时间 制作编译用的镜像 测试修改后的实施时间 概要 使用 docker 打包镜像的时候, 每次耗费时间最多的就是 docker build 的过程. 特别是对于前端工程的打包, ...
- 如何配置jdk的本地环境
在计算机→属性→高级系统设置→高级→环境变量,如图: 第一步:系统变量→新建 JAVA_HOME 变量 . 变量值填写jdk的安装目录(本人是C:\Program Files\Java\jdk1.8. ...
- pandas使用大全--数据与处理
1.首先导入pandas库,一般都会用到numpy库,所以我们先导入备用: import numpy as np import pandas as pd 导入CSV或者xlsx文件: df = pd. ...
- mysql8 安装
准备工作: 首先安装这些依赖 yum install -y flex yum install gcc gcc-c++ cmake ncurses ncurses-devel bison libaio ...
- 分布式中session共享的解决方案:spring-session
Session是客户端与服务器通讯会话跟踪技术,是服务器与客户端保持整个通讯的会话基本信息.客户端在第一次访问服务器的时候,服务端会响应一个sessionId并且将它存入到本地的Cookie中,在之后 ...
- 使用 Xbox Game 录制桌面视频(录制音频)
使用 Xbox Game 录制桌面视频(附带音频) 前言:可能自己音频输出的问题,一直无法用工具录制桌面的音频,而最后发现利用 Xbox Game 录制游戏视频的功能很好地解决我们的问题. 1)打开游 ...
- C# 人民币大写金额转换
/// <summary> /// 转换人民币大小金额 /// </summary> /// <param name="nu ...
- 2、Ext.NET 1.7 官方示例笔记-按钮
这一节应该比较简单,因为按钮相对其他控件还是比较简单的,但按钮是最常用的控件,先从简单的开始,才能循序渐进的学下去不是吗? 从上面的图片可以看出,可分基本&按钮组,先看下基本的Overview ...
- Java编程基础——流程控制
Java编程基础——流程控制 摘要:本文主要介绍Java编程中的流程控制语句. 分类 流程控制指的是在程序运行的过程中控制程序运行走向的方式.主要分为以下三种: 顺序结构:从上到下依次执行每条语句操作 ...
- C# 获取社会统一信用代码
时间不多,废话少说: 网络请求代码如下: using System; using System.Collections.Generic; using System.Linq; using System ...