<一>事件

事件主要用于线程间传递消息,通过事件来控制一个线程是处于执行状态还是处于挂起状态。

事件和互斥量之间的差别:

  1. 事件主要用于协调两个或者多个线程之间的动作,使其协调一致,符合逻辑。一个线程等待某个事件的发生,另一个线程则在事件发生后产生一个信号,通知那个正在等待的线程(我的理解:线程A等待键盘输入,线程B在有键盘输入后发送一个信号给A,使得A可以执行,事件就是“键盘输入”)。
  2. 互斥量主要是为了保证在任何时刻只有一个线程在使用共享资源,线程的运行次序是随机的,有操作系统决定,因此互斥量不能使两个线程按一定的顺序执行。
  3. 互斥量有信号状态是指线程正在拥有该互斥量,无信号是指没有线程拥有这个互斥量;对事件来说,当等待的事件发生时,事件对象处于活动状态,叫有信号状态,相反的,当等待的事件没有发生时,事件对象处于无信号状态。
  4. 事件一般分为两种:手动事件和自动事件。手动事件是指当事件对象处于活动状态时它会一直处于这个状态,直到显示地将其置为无信号状态;自动事件是指当事件处于有信号状态并有一个线程接收到该事件后,事件立即变为无信号状态。

<二>与事件有关的函数

函数名 作用
CreateEvent 创建一个事件
OpenEvent 打开一个已经创建的事件
SetEvent 触发一个事件
ResetEvent 复位一个事件
PulseEvent 触发并重置一个事件
WaitForSingleObject 等待单个事件
WaitForMultipleObject 等待多个事件
#include <windows.h>
#include <process.h> /* _beginthread, _endthread */
#include <iostream>
#include <fstream>
using namespace std; HANDLE hEvent; unsigned long _stdcall MyThread1(LPVOID lpParam)
{
cout<<"Wait for event\n";
WaitForSingleObject(hEvent,INFINITE);
cout<<"Get the event\n";
return ;
} unsigned long _stdcall MyThread2(LPVOID lpParam)
{
Sleep();
cout<<"Signal the event\n";
SetEvent(hEvent);
return ;
} int main()
{
HANDLE handle1,handle2;
DWORD dw1,dw2;
hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
handle1 =CreateThread(NULL,NULL,MyThread1,NULL,NULL,&dw1);
handle2 =CreateThread(NULL,NULL,MyThread2,NULL,NULL,&dw2); Sleep(); CloseHandle(handle1);
CloseHandle(handle2);
CloseHandle(hEvent); return ;
}

再看一个难一点的例子:两个读线程,一个写线程。

#include <windows.h>
#include <process.h> /* _beginthread, _endthread */
#include <iostream>
#include <fstream>
using namespace std; HANDLE hWriteEvent;
HANDLE hReadEvent[]; int buff[]; CRITICAL_SECTION cs;
BOOL isRunning = true; unsigned long _stdcall WriteThread(LPVOID lpParam)
{
hWriteEvent = CreateEvent(NULL,TRUE,FALSE,NULL);//创建一个写事件,并处于有信号状态
int k = ;
while (isRunning)
{
if(WAIT_OBJECT_0==WaitForMultipleObjects(,hReadEvent,true,))
{
for (int i = ;i<;i++)
{
buff[i]=(i+)*k;
}
k++;
PulseEvent(hWriteEvent);
}
}
return ;
} unsigned long _stdcall ReadThread1(LPVOID lpParam)
{
hReadEvent[] = CreateEvent(NULL,FALSE,TRUE,NULL);
while (isRunning)
{
WaitForSingleObject(hWriteEvent,INFINITE);
EnterCriticalSection(&cs);
cout<<"Print from Thread #1:";
for (int i = ;i<;i++)
cout<<buff[i]<<" "; cout<<endl;
LeaveCriticalSection(&cs);
SetEvent(hReadEvent[]); }
return ;
} unsigned long _stdcall ReadThread2(LPVOID lpParam)
{
hReadEvent[] = CreateEvent(NULL,FALSE,TRUE,NULL);
while (isRunning)
{
WaitForSingleObject(hWriteEvent,INFINITE);
EnterCriticalSection(&cs);
cout<<"Print from Thread #2:";
for (int i = ;i<;i++)
cout<<buff[i]<<" "; cout<<endl;
LeaveCriticalSection(&cs);
SetEvent(hReadEvent[]); }
return ;
} unsigned long _stdcall ControlThread(LPVOID lpParam)
{
isRunning = FALSE;
return ;
} int main()
{
HANDLE handle1,handle2,handle3,handle4;
DWORD dw1,dw2,dw3,dw4;
InitializeCriticalSection(&cs); handle1 = CreateThread(NULL,,WriteThread,NULL,,&dw1);
handle2 = CreateThread(NULL,,ReadThread1,NULL,,&dw2);
handle3 = CreateThread(NULL,,ReadThread2,NULL,,&dw3);
Sleep();
handle4 = CreateThread(NULL,,ControlThread,NULL,,&dw4); CloseHandle(handle1);
CloseHandle(handle2);
CloseHandle(handle3);
CloseHandle(handle4);
CloseHandle(hWriteEvent);
CloseHandle(hReadEvent[]);
CloseHandle(hReadEvent[]); return ;
}

Windows环境下多线程编程原理与应用读书笔记(7)————事件及其应用的更多相关文章

  1. Windows环境下多线程编程原理与应用读书笔记(1)————基本概念

    自从学了操作系统知识后,我就对多线程比较感兴趣,总想让自己写一些有关多线程的程序代码,但一直以来,发现自己都没怎么好好的去全面学习这方面的知识,仅仅是完成了操作系统课程上的小程序,对多线程的理解也不是 ...

  2. Windows环境下多线程编程原理与应用读书笔记(3)————Windows环境中的多线程实现(3)

    纤程 纤程(fiber): 相当于用户级别的线程或轻进程.纤程由Win32库函数支持,对核心是不可见的.纤程可以通过SwitchToFiber显示至另一合作纤程,以实现合作纤程之间的协同.线程是在Wi ...

  3. Windows环境下多线程编程原理与应用读书笔记(8)————信号量及其应用

    <一>线程间同步原因 线程间竞争共享资源: 线程间为完成某个任务而协作: 通过互斥量可以实现线程间由于竞争所需要的同步,通过事件可以实现线程间由于协作所需要的同步. 信号量很好地将互斥量和 ...

  4. Windows环境下多线程编程原理与应用读书笔记(6)————临界段及其应用

    <一>临界段 临界段对象通过提供所有线程必须共享的对象来控制线程.只有拥有临界段对象的线程才能够访问保护的资源.在另一个线程可以访问该资源之前,前一线程必须释放临界段对象,一遍新的线程可以 ...

  5. Windows环境下多线程编程原理与应用读书笔记(5)————互斥及其应用

    <一>互斥的同步机制 思想:当一个线程获得互斥量了后,其他所有要获取同一个互斥量的线程都处于阻塞状态,直到第一个线程释放互斥量为止. 设想几个线程竞争同一个互斥量,其中一个线程获得了互斥量 ...

  6. Windows环境下多线程编程原理与应用读书笔记(2)————面向对象技术

    面向对象技术是学C++需要重点掌握的知识,因为我觉得自己的基础还是比较可以,这一章节的内容就只是粗略的读了一遍,在此就不做过多的笔记.

  7. Windows环境下多线程编程原理与应用读书笔记(4)————线程间通信概述

    <一>线程间通信方法 全局变量方式:进程中的线程共享全局变量,可以通过全局变量进行线程间通信. 参数传递法:主线程创建子线程并让子线程为其服务,因此主线程和其他线程可以通过参数传递进行通信 ...

  8. Java多线程编程实战指南 设计模式 读书笔记

    线程设计模式在按其有助于解决的多线程编程相关的问题可粗略分类如下. 不使用锁的情况下保证线程安全: Immutable Object(不可变对象)模式.Thread Specific Storage( ...

  9. 关于docker在windows环境下运行的第一次体验

    关于docker在windows环境下执行的原理 1.1.           首先是Docker Quickstart启动,如果在虚拟机Oracle VM VirtualBox不存在default虚 ...

随机推荐

  1. 将Editplus添加到右键打开菜单

    因为自己一直用Editplus作为文本打开工具,新的电脑将压缩文件复制了过来,但是没有右键打开了. 第一打开注册表 在命令框中输入regedit 第二在注册表中输入选项 如下图所示在下拉菜单中新建Ed ...

  2. angular学习笔记03 理论加实践

    novalidate 属性是在 HTML5 中新增的.禁用了使用浏览器的默认验证. //augular.js自定义指令 .directive('runoobDirective',function(){ ...

  3. 【转】String字符串相加的问题

    String字符串相加的问题 前几天同事跟我说我之前写的代码中在操作字符串时候,使用字符串相加的方式而不是使用StringBuffer或者StringBuilder导致内存开销很大.这个问题一直在困扰 ...

  4. 每周分享之 二 http协议(2)

    本次分享http协议,共分为三部分,这是第二部分,主要讲解请求与响应的字段,以及状态码. 以http/1.1版本的一个完整的请求与响应作为例子 http请求信息由三部分组成 1.请求方法(GET/PO ...

  5. PowerBI开发 第七篇:数据集和数据刷新

    PowerBI报表是基于数据分析的引擎,数据真正的来源(Data Source)是数据库,文件等数据存储媒介,PowerBI支持的数据源类型多种多样.PowerBI Service(云端)有时不直接访 ...

  6. IntelliJ IDEA 14.1.4设置关闭自动保存和标志改动文件为星号?

    一.设置取消默认的自动保存: 二.设置文件内容改动后为文件标题头部添加*号:

  7. 苹果手机使用替代onkeyup的方法

    今天项目有这个问题,苹果手机就不行   使用keyup事件检测文本框内容:  $('#keyup_i').bind('keyup', function(){         $('#keyup_s') ...

  8. js-location应用

    1 location.search ?xxx=sss&yyy=ddd 获取地址中查询的值 /** * 解析url参数 * @example ?id=123456&a=b * @retu ...

  9. JAVAEE企业级应用开发浅谈第一辑

    不积跬步无以至千里,不积小流无以成江海 Step1.情景概要 作为一个JAVA WEB 开发人员,在开发web 项目时项目大家都有自己的一些新的体会,对于web 开发出现的一些比较经典的名词大家都会有 ...

  10. ABAP POH和POV事件中 获得屏幕字段的值

    在Screen显示之前,系统会自动将程序变量值放到屏幕字段中:在PAI事件中,系统会自动将屏幕字段的值更新到相应的程序变量. 在Screen Logic中我们还有POH和POV事件,所以有时需要调用函 ...