Windows环境下多线程编程原理与应用读书笔记(7)————事件及其应用
<一>事件
事件主要用于线程间传递消息,通过事件来控制一个线程是处于执行状态还是处于挂起状态。
事件和互斥量之间的差别:
- 事件主要用于协调两个或者多个线程之间的动作,使其协调一致,符合逻辑。一个线程等待某个事件的发生,另一个线程则在事件发生后产生一个信号,通知那个正在等待的线程(我的理解:线程A等待键盘输入,线程B在有键盘输入后发送一个信号给A,使得A可以执行,事件就是“键盘输入”)。
- 互斥量主要是为了保证在任何时刻只有一个线程在使用共享资源,线程的运行次序是随机的,有操作系统决定,因此互斥量不能使两个线程按一定的顺序执行。
- 互斥量有信号状态是指线程正在拥有该互斥量,无信号是指没有线程拥有这个互斥量;对事件来说,当等待的事件发生时,事件对象处于活动状态,叫有信号状态,相反的,当等待的事件没有发生时,事件对象处于无信号状态。
- 事件一般分为两种:手动事件和自动事件。手动事件是指当事件对象处于活动状态时它会一直处于这个状态,直到显示地将其置为无信号状态;自动事件是指当事件处于有信号状态并有一个线程接收到该事件后,事件立即变为无信号状态。
<二>与事件有关的函数
函数名 | 作用 |
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)————事件及其应用的更多相关文章
- Windows环境下多线程编程原理与应用读书笔记(1)————基本概念
自从学了操作系统知识后,我就对多线程比较感兴趣,总想让自己写一些有关多线程的程序代码,但一直以来,发现自己都没怎么好好的去全面学习这方面的知识,仅仅是完成了操作系统课程上的小程序,对多线程的理解也不是 ...
- Windows环境下多线程编程原理与应用读书笔记(3)————Windows环境中的多线程实现(3)
纤程 纤程(fiber): 相当于用户级别的线程或轻进程.纤程由Win32库函数支持,对核心是不可见的.纤程可以通过SwitchToFiber显示至另一合作纤程,以实现合作纤程之间的协同.线程是在Wi ...
- Windows环境下多线程编程原理与应用读书笔记(8)————信号量及其应用
<一>线程间同步原因 线程间竞争共享资源: 线程间为完成某个任务而协作: 通过互斥量可以实现线程间由于竞争所需要的同步,通过事件可以实现线程间由于协作所需要的同步. 信号量很好地将互斥量和 ...
- Windows环境下多线程编程原理与应用读书笔记(6)————临界段及其应用
<一>临界段 临界段对象通过提供所有线程必须共享的对象来控制线程.只有拥有临界段对象的线程才能够访问保护的资源.在另一个线程可以访问该资源之前,前一线程必须释放临界段对象,一遍新的线程可以 ...
- Windows环境下多线程编程原理与应用读书笔记(5)————互斥及其应用
<一>互斥的同步机制 思想:当一个线程获得互斥量了后,其他所有要获取同一个互斥量的线程都处于阻塞状态,直到第一个线程释放互斥量为止. 设想几个线程竞争同一个互斥量,其中一个线程获得了互斥量 ...
- Windows环境下多线程编程原理与应用读书笔记(2)————面向对象技术
面向对象技术是学C++需要重点掌握的知识,因为我觉得自己的基础还是比较可以,这一章节的内容就只是粗略的读了一遍,在此就不做过多的笔记.
- Windows环境下多线程编程原理与应用读书笔记(4)————线程间通信概述
<一>线程间通信方法 全局变量方式:进程中的线程共享全局变量,可以通过全局变量进行线程间通信. 参数传递法:主线程创建子线程并让子线程为其服务,因此主线程和其他线程可以通过参数传递进行通信 ...
- Java多线程编程实战指南 设计模式 读书笔记
线程设计模式在按其有助于解决的多线程编程相关的问题可粗略分类如下. 不使用锁的情况下保证线程安全: Immutable Object(不可变对象)模式.Thread Specific Storage( ...
- 关于docker在windows环境下运行的第一次体验
关于docker在windows环境下执行的原理 1.1. 首先是Docker Quickstart启动,如果在虚拟机Oracle VM VirtualBox不存在default虚 ...
随机推荐
- overflow使用說明
必須設置的CSS屬性: { display:block; //或者inline-block,text-overflow:ellipsis只對block或者inline-block有效 white-sp ...
- Spring c3p0连接池无法释放解决方案
通过c3p0配置连接池的时候,在进行压力测试的时候,日志出现了这样一个错误:Data source rejected establishment of connection, message from ...
- jsonp其实很简单【ajax跨域请求】
js便签笔记(13)——jsonp其实很简单[ajax跨域请求] 前两天被问到ajax跨域如何解决,还真被问住了,光知道有个什么jsonp,迷迷糊糊的没有说上来.抱着有问题必须解决的态度,我看了许多资 ...
- 变量的声明和定义以及extern的用法
变量的声明和定义以及extern的用法 变量的声明不同于变量的定义,这一点往往容易让人混淆. l 变量 ...
- axis和cxf集成Springmvc的使用
一.使用axis用wsdl生成Webservice: 工具:有axis插件的eclipse,wsdl文件: 操作步骤: 新建工程-->选择wsdl文件-->右键选择Webservice-- ...
- Ubuntu 16安装GPU版本tensorflow
pre { direction: ltr; color: rgb(0, 0, 0) } pre.western { font-family: "Liberation Mono", ...
- Java历程-初学篇 Day08 数组
一,什么是数组 所谓数组,是相同数据类型的元素按一定顺序排列的集合.若将有限个类型相同的变量的集合命名,那么这个名称为数组名.组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量.用 ...
- nodejs后台集成富文本编辑器(ueditor)
1 下载ueditor nodejs版本 2 复制public目录下面的文件 到项目静态资源public文件夹下 3 在项目根目录创建ueditor文件夹 要复制进来的内容为 4 在根目录的 uedi ...
- WPF DataGrid Custommization using Style and Template
WPF DataGrid Custommization using Style and Template 代码下载:http://download.csdn.net/detail/wujicai/81 ...
- Hadoop通过HCatalog编写Mapreduce任务访问hive库中schema数据
1.dirver package com.kangaroo.hadoop.drive; import java.util.Map; import java.util.Properties; impor ...