<一>事件

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

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

  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. 为什么自学java的人99%都学不会?

    在学习java这条路上,有一类自学的学员,总让我感慨良多.这类学员,往往每天表现非常勤奋的学习,但学会的人却很少.他们极期勤奋,那么努力的学,也很认真,为什么就是学不会java呢? 通过小橙子我的大量 ...

  2. Spring+SpringMVC+MyBatis整合进阶篇(四)RESTful实战(前端代码修改)

    前言 前文<RESTful API实战笔记(接口设计及Java后端实现)>中介绍了RESTful中后端开发的实现,主要是接口地址修改和返回数据的格式及规范的修改,本文则简单介绍一下,RES ...

  3. TCP/IP(一)之初识计算机网络

    前言 在一段时间里,都很想知道一台电脑怎么跟另一台电脑通信的,我发送一个qq给女朋友,怎么准确的发送过去的,又是怎么接受消息的. 接下来一段时间给大家慢慢分享关于计算机网络的相关知识. 一.局域网.广 ...

  4. Java钉钉开发_01_开发前的准备

    源码已上传GitHub:传送门 一.准备事项 1.1  一个能在公网上访问的项目: 参见:Java微信开发_02_本地服务器映射外网 1.2  一个钉钉账号 去注册 1.3 创建一个应用 登录钉钉后台 ...

  5. Linux学习——shell编程之运算符

    shell编程之运算符 一:shell中常见算术运算符号和优先级 二:算术运算符 Shell 变量:是弱类型!不能进行加减乘除!比较麻烦! 例子 :shell变量弱类型 a=11 b=22 echo ...

  6. http://codeforces.com/problemset/problem/847/E

    E. Packmen time limit per test 1 second memory limit per test 256 megabytes input standard input out ...

  7. python---time模块使用详解

    python中的time模块提供一些方法用来进行关于时间的操作,time模块中有以下方法可供使用: time() --- 返回当前时间的时间戳. 调用:time.time(),  可用于计算程序运行的 ...

  8. Java+Velocity模板引擎集成插件到Eclipse及使用例子

    一.因为我用的是当前最新的Eclipse4.5,Eclipse中安装集成VelocityEclipse插件之前需要先安装其支持插件:Eclipse 2.0 Style Plugin Support 1 ...

  9. FPGA在电平接口领域的应用

    电子技术的发展,产生了各种各样的电平接口. TTL电平: TTL电平信号之所以被广泛使用,原因是因为:通常我们采用二进制来表示数据.而且规定,+5V等价于逻辑"1",0V等价于逻辑 ...

  10. 跨平台的 NodeJS 组件解决 .NetCore 不支持 System.Drawing图形功能的若干问题

    问题 生成缩略图 生成验证码 生成二维码 给图片加水印 外部引用 Node  不解释  https://nodejs.org/en/download/ sharp 高性能缩略图  https://gi ...