事件和互斥体同样属于内核同步对象,它和互斥体以及临界区在功能上有以下区别

前面的互斥体和临界区主要作用在于确保控制多个线程之间对共享资源访问,保证共享资源的完整性

事件主要作用是通知其它线程一个操作己经完成,可以接下来执行后面剩余操作了,确保多个线程之间的动作以指定的次序发生

例如:一个线程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事件的更多相关文章

  1. {python--GIL锁}一 介绍 二 GIL介绍 三 GIL与Lock 四 GIL与多线程 五 多线程性能测试

    python--GIL锁 GIL锁 本节目录 一 介绍 二 GIL介绍 三 GIL与Lock 四 GIL与多线程 五 多线程性能测试 一 背景知识 ''' 定义: In CPython, the gl ...

  2. php Pthread 多线程 (五) 线程同步

    有些时候我们不希望线程调用start()后就立刻执行,在处理完我们的业务逻辑后在需要的时候让线程执行. <?php class Sync extends Thread { private $na ...

  3. C#多线程之线程同步篇2

    在上一篇C#多线程之线程同步篇1中,我们主要学习了执行基本的原子操作.使用Mutex构造以及SemaphoreSlim构造,在这一篇中我们主要学习如何使用AutoResetEvent构造.Manual ...

  4. Linux多线程编程——多线程与线程同步

    多线程 使用多线程好处: 一.通过为每种事件类型的处理单独分配线程,可以简化处理异步事件的代码,线程处理事件可以采用同步编程模式,启闭异步编程模式简单 二.方便的通信和数据交换 由于进程之间具有独立的 ...

  5. C#简单多线程使用(同步和优先权)

    题目: 麦当劳有两个做汉堡的厨师(工号:11,12)和三个销售人员(工号:21,22,23). 厨师生产汉堡,并负责将做好的汉堡放入货架,货架台大小有限,最多放6个汉堡,11和12不能同时往货架台上放 ...

  6. 多线程(五) java的线程锁

    在多线程中,每个线程的执行顺序,是无法预测不可控制的,那么在对数据进行读写的时候便存在由于读写顺序多乱而造成数据混乱错误的可能性.那么如何控制,每个线程对于数据的读写顺序呢?这里就涉及到线程锁. 什么 ...

  7. python 多进程/多线程/协程 同步异步

    这篇主要是对概念的理解: 1.异步和多线程区别:二者不是一个同等关系,异步是最终目的,多线程只是我们实现异步的一种手段.异步是当一个调用请求发送给被调用者,而调用者不用等待其结果的返回而可以做其它的事 ...

  8. C# 多线程之线程同步

    多线程间应尽量避免同步问题,最好不要线程间共享数据.如果必须要共享数据,就需要使用同步技术,确保一次只有一个线程访问和改变共享状态. 一::lock语句 lock语句事设置锁定和接触锁定的一种简单方法 ...

  9. MFC——9.多线程与线程同步

    Lesson9:多线程与线程同步 程序.进程和线程是操作系统的重点,在计算机编程中.多线程技术是提高程序性能的重要手段. 本文主要解说操作系统中程序.进程和线程之间的关系,并通过相互排斥对象和事件对象 ...

随机推荐

  1. SecureCRT自动断开连接的解决方法

    方法一: 在普通用户下,输入重启sshd服务的命令:service sshd restart 这时会提示:管理系统服务或单元需要身份验证.解决的方法:先要切换为root用户,接着重启sshd服务:se ...

  2. python27期尚哥讲数据库:

    1.下载:https://www.mysql.com/ DOWNLOADS MySQL Community (GPL) Downloads »-- MySQL Community Server Loo ...

  3. zz《可伸缩服务架构 框架与中间件》综合

    第1章 如何设计一款永不重复的高性能分布式发号器 1. 为什么不直接采用UUID? 虽然UUID能够保证唯一性,但无法满足业务系统需要的很多其他特性,比如时间粗略有序性.可反解和可制造性(说人话,就是 ...

  4. html头部标签汇总

    <!DOCTYPE html> <!-- 使用 HTML5 doctype,不区分大小写 --> <html lang="zh-cmn-Hans"&g ...

  5. ubuntu串口连接linux车机设备

    一.用到的命令或者程序 1.dmesg命令 2.minicom软件 二.开搞 1.安装minicom sudo apt-get install minicom 2.查看串口信息 dmesg | gre ...

  6. 【Java语言特性学习之五】版本差异新特性

  7. 坑爹的京东E卡(京东E卡的正确使用方式)

      前言    今年中秋公司发了200的京东E卡(下面简称礼品卡,京东简称jd)这让喜欢在jd自营购买商品的我很是开心,    兴致勃勃打开官网,当我选好商品准备结算时却发现礼品卡无法使用.    后 ...

  8. 七道常见的Redis面试题分享(含个人解答)

    绝大部分写业务的程序员,在实际开发中使用 Redis 的时候,只会 Set Value 和 Get Value 两个操作,对 Redis 整体缺乏一个认知.这里以面试题的形式对 Redis 常见问题做 ...

  9. Solr单机版的安装与使用

    .使用Solr实现. 基于Solr实现站内搜索扩展性较好并且可以减少程序员的工作量,因为Solr提供了较为完备的搜索引擎解决方案,因此在门户.论坛等系统中常用此方案. .什么是Solr. Solr是A ...

  10. minggw 安装

    windows上如果没有安装 visual studio, 也就是俗称的vs, 在安装一些带有c或者c++代码的Python模块的时候, 会报错Unable to find vcvarsall.bat ...