第三章 Windows多线程编程.

Slides:



Advertisements
Similar presentations
7.1 内置对象概述及分类 JSP 视频教学课程. JSP2.2 目录 1. 内置对象简介 1. 内置对象简介 2. 内置对象分类 2. 内置对象分类 3. 内置对象按功能区分 3. 内置对象按功能区分 4. 内置对象作用范围 4. 内置对象作用范围.
Advertisements

面向侧面的程序设计 方林博士 本文下载地址:
高级服务器设计和实现 1 —— 基础与进阶 余锋
阻塞操作. 在 linux 里,一个等待队列由一个 wait_queue_head_t 类型的结构来描述 等待队列的初始化: static wait_queue_head_t testqueue; init_waitqueue_head(&testqueue);
Linux 系统. 操作系统发展需求 1 没有操作系统 2 简单批处理操作系统 3 多道程序设计的批处理 4 多道程序设计的分时操作系统 5 多处理机并行系统 6 网络操作系统 7 分布式操作系统.
Oracle数据库 Oracle 子程序.
Windwos 多线程程序设计 多线程概述 Win32 API对多线程编程的支持 线程之间的同步 哲学家进餐问题分析与实现.
C++中的声音处理 在传统Turbo C环境中,如果想用C语言控制电脑发声,可以用Sound函数。在VC6.6环境中如果想控制电脑发声则采用Beep函数。原型为: Beep(频率,持续时间) , 单位毫秒 暂停程序执行使用Sleep函数 Sleep(持续时间), 单位毫秒 引用这两个函数时,必须包含头文件
全国计算机等级考试 二级基础知识 第二章 程序设计基础.
在PHP和MYSQL中实现完美的中文显示
Kvm异步缺页中断 浙江大学计算机体系结构实验室 徐浩.
Hadoop I/O By ShiChaojie.
OpenMP简介和开发教程 广州创龙电子科技有限公司
实践演练 广州创龙电子科技有限公司 01 广州创龙电子科技有限公司
走进编程 程序的顺序结构(二).
辅导课程六.
网络常用常用命令 课件制作人:谢希仁.
临界区软件互斥软件实现算法.
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
Windows网络操作系统管理 ——Windows Server 2008 R2.
Online job scheduling in Distributed Machine Learning Clusters
本节内容 模拟线程切换 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
临界区软件互斥软件实现算法 主讲教师:夏莹杰
用event class 从input的root文件中,由DmpDataBuffer::ReadObject读取数据的问题
华南理工大学 陈虎 博士 多核处理器上的操作系统 华南理工大学 陈虎 博士
宁波市高校慕课联盟课程 与 进行交互 Linux 系统管理.
宁波市高校慕课联盟课程 与 进行交互 Linux 系统管理.
第一章 函数与极限.
实验二、线程同步与通信 一、实验目的 1、掌握Linux下线程的概念; 2、了解Linux线程同步与通信的主要机制;
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
内容摘要 ■ 课程概述 ■ 教学安排 ■ 什么是操作系统? ■ 为什么学习操作系统? ■ 如何学习操作系统? ■ 操作系统实例
简单介绍 用C++实现简单的模板数据结构 ArrayList(数组, 类似std::vector)
本节内容 随机读取 视频提供:昆山爱达人信息技术有限公司.
实验四、TinyOS执行机制实验 一、实验目的 1、了解tinyos执行机制,实现程序异步处理的方法。
分裂对象模型 C++ otcl.
<编程达人入门课程> 本节内容 内存的使用 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群: ,
Select模型 本节内容 视频提供:昆山爱达人信息技术有限公司 视频录制:yang 官网地址:
本节内容 Win32 API中的宽字符 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
信号量(Semaphore).
第4章 Excel电子表格制作软件 4.4 函数(一).
_08文件的基本操作 本节课讲师——void* 视频提供:昆山爱达人信息技术有限公司 官网地址:
本节内容 内存复制指令 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
iSIGHT 基本培训 使用 Excel的栅栏问题
_13简单的GDI绘图操作 本节课讲师——void* 视频提供:昆山爱达人信息技术有限公司 官网地址:
本节内容 文件系统 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
Chapter 18 使用GRASP的对象设计示例.
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
Visual Basic程序设计 第13章 访问数据库
本节内容 模块隐藏 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
3.1私有内存的分配.
临界区问题的硬件指令解决方案 (Synchronization Hardware)
本节内容 C语言的汇编表示 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
本节内容 Windows线程切换_时钟中断切换 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
WSAAsyncSelect 模型 本节内容 视频提供:昆山爱达人信息技术有限公司 视频录制:yang
第9章 多 线 程.
Google的云计算 分布式锁服务Chubby.
_07多连接之select模型 本节课讲师——void* 视频提供:昆山爱达人信息技术有限公司 官网地址:
阻塞式模型 本节内容 视频提供:昆山爱达人信息技术有限公司 视频录制:yang 官网地址:
基于列存储的RDF数据管理 朱敏
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
本节内容 动态链接库 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
《手把手教你学STM32-UCOS》 主讲人 :正点原子团队 硬件平台:正点原子STM32开发板 版权所有:广州市星翼电子科技有限公司
第8章 创建与使用图块 将一个或多个单一的实体对象整合为一个对象,这个对象就是图块。图块中的各实体可以具有各自的图层、线性、颜色等特征。在应用时,图块作为一个独立的、完整的对象进行操作,可以根据需要按一定比例和角度将图块插入到需要的位置。 2019/6/30.
WEB程序设计技术 数据库操作.
本节内容 进程 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第十七讲 密码执行(1).
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
<编程达人入门课程> 本节内容 有符号数与无符号数 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
本节内容 SEMAPHORE 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
Presentation transcript:

第三章 Windows多线程编程

主要内容 Windows操作系统的一些基本知识 Win32 API线程库 线程间通信 调度优先级

1. Windows操作系统的一些基本知识

API ( Application Programming Interface ) 32位版本Windows的API被称为Win32 直接用Win32 API编写的应用程序,程序的执行代码小,运行效率高 MFC用类库的方式将Win32 API 进行封装, 以类的方式提供给开发者 Framework类库提供了所有应用程序模型都要使用的一个面向对象的API集合

内核对象及句柄 内核对象是由操作系统内核分配的,只能由内核访问的一个内存块,用来供系统和应用程序使用和管理各种系统资源。 内核对象包括:符号对象、事件对象、文件映射对象、I/O完成端口对象、作业对象、信箱对象、互斥量、管道对象、进程对象、信标对象、线程对象和等待计时器对象等,这些对象通过调用函数来创建。 不同的对象拥有不同的数据结构,它的成员负责维护该对象的各种信息。

内核对象及句柄 如何操作内核对象? Windows提供了一组函数,使用这组函数来访问内核对象。 创建内核对象的函数,会返回一个句柄,任何线程都可以使用这个值,把这个句柄传递给Windows的各个函数,系统就知道操作哪个内核对象了。 进程被初始化时,系统为它分配一个句柄表,用于保存该进程使用的内核对象的信息,而句柄值则是相应内核对象在句柄表中的索引值,因此句柄值是进程相关的。 内核对象由内核拥有,各个进程可以共享内核对象。进程中止执行,它使用的内核对象并不一定会被撤销。

2. Win32 API的线程库

2.1 创建线程的基本问题 线程可以由进程中的任意线程创建,而进程的主线程在进程加载时自动创建。 每个线程都有自己的进入点函数。 主线程的进入点函数

线程函数----线程的入口点 线程函数的返回值是该线程的退出代码 线程函数应尽可能使用函数参数和局部变量

2.2 创建线程的API函数 当创建线程时,系统创建一个线程内核对象。该线程内核对象不是线程本身,而是操作系统用来管理线程的较小的数据结构 安全属性 NULL /STACK:[reserve][commit] 控制创建线程标志 线程ID 当创建线程时,系统创建一个线程内核对象。该线程内核对象不是线程本身,而是操作系统用来管理线程的较小的数据结构 在进程的地址空间分配内存,供线程的堆栈使用

C/C++多线程运行期库中 线程创建函数 _beginthreadex

_beginthreadex函数在创建线程之前会为线程分配数据块(tiddata),并对数据块初始化,然后将数据块与线程联系起来 再为线程函数建立结构异常化处理帧来处理线程函数中的异常。

2.3 操作线程的API 暂停线程 返回值是线程的前一个暂停计数 线程暂停是线程内核对象的一个内部值,用于指明线程的暂停计数。 使用要小心,因为不知道暂停线程运行时它在进行什么操作。可能造成死锁

2.3 操作线程的API 恢复线程 返回值是线程的前一个暂停计数 该函数用于将处于暂停状态的线程置于就绪状态,使其参加线程调度。

2.3 操作线程的API 使线程睡眠 该函数是线程暂停自己的运行,直到睡眠时间过去为止 当线程调用这个函数时,它自动放弃剩余的时间片,迫使系统进行线程调度。 Windows不是实时的操作系统。

2.3 操作线程的API 终止线程 线程函数返回(最好) 通过调用ExitThread函数,线程将自行撤销 同一个进程或另一个进程中的线程调用TerminateThread函数 包含线程的进程终止

线程返回函数 线程中创建的C++类对象能够正常撤销 操作系统将正确地释放线程堆栈使用的内存 系统将线程的退出代码(线程内核对象维护)设置为线程函数的返回值 系统将递减线程内核对象的使用计数

ExitThread函数 线程调用这个函数,强制线程终止运行 导致操作系统清除该线程使用的所有操作系统资源。 C++类对象将不被撤销。

TerminateThread函数 能够撤销任何线程 线程的内核对象的使用计数也被递减 异步运行的函数 不撤销线程的堆栈,直到进程终止

在进程终止运行时撤销线程 ExitProcess 和 TerminateProcess函数可以终止线程,这些线程将会终止进程中的所有线程 进程所使用的资源被清除 剩余线程被撤销 C++对象撤销函数没有被调用

线程内核对象示意图

在进程终止运行时撤销线程

2.4 一个简单的Windows多线程程序

3. 线程间通信 操作系统随机调度线程,程序员不能预知线程的执行顺序

3. 线程间通信 下面两种情况下,线程间需要通信 Windows线程通信方法主要有互锁函数、临界段、事件、互斥量、信号量 当有多个线程访问共享资源而不希望共享资源遭到破坏;(互斥) 当一个线程需要将某个任务已经完成的情况通知另外一个或多个线程时。(同步) Windows线程通信方法主要有互锁函数、临界段、事件、互斥量、信号量

3.1 互锁函数 互锁函数是用来解决原子访问的,主要针对变量的原子访问; 原子访问:当线程访问资源时,能够确保没有其它线程同时访问相同的资源。

例子 Long g_x = 0; //全局变量 DWORD WINAPI ThreadFunc1 (PVOID pvParam) { return 0; } DWORD WINAPI ThreadFunc2 (PVOID pvParam) MOV EAX, [g_x] INC EAX MOV [g_x], EAX 递增以原子方式运行

3.1 互锁函数 LONG InterlockedExchangeAdd()( PLONG plAddend, LONG lIncrement); Long g_x=0; //全局变量 DWORD WINAPI ThreadFunc1 (PVOID pvParam) { InterlockedExchangeAdd(&g_x,1); return 0; } DWORD WINAPI ThreadFunc2 (PVOID pvParam)

3.1 互锁函数 以原子操作方式用第二个参数的值取代第一个参数的当前值。 LONG InterlockedExchange ()( PLONG plTarget, LONG lValue); LONG InterlockedExchangePointer ()( PVOID* ppvTarget, PVOID pvValue);

3.1 互锁函数 比较第一个参数所指的值和第三个参数的值,如果相等,则将第一个参数所指的值置为第二个参数,如果不相等则不进行任何操作。 LONG InterlockedCompareExchange ()( PLONG plDestination, LONG lExchange, LONG lComparand); LONG InterlockedCompareExchangePointer ()( PVOID* ppvDestination, PVOID pvExchange, PVOID pvComparand);

3.2 临界段 互锁函数:以原子操作方式修改单个值 临界段:以原子方式修改复杂的数据结构。 临界段:关键代码段,是指一小段代码,同一个时刻,只能有一个线程具有访问权。 多个线程访问同一个临界区的原则: 一次最多只能一个线程停留在临界区内; 不能让一个线程无限地停留在临界区内,否则其它线程将不能进入该临界区

临界段相关API函数 4个函数用于临界段 首先定义一个临界段对象(通常全局变量) 临界段对象初始化 进入临界段 离开临界段 释放临界段对象

临界段应用举例

加上临界段

3.3 使用内核对象的线程间通信 互锁函数和临界段都是在用户态实现线程通信的,优点速度快 用户态机制只能实现同一进程内线程通信。 内核对象机制的适应性优于用户态机制,缺点速度慢。 包含通知状态和未通知状态内核属性的内核对象有: 进程,线程,作业,文件,控制台输入 文件修改通知,事件,可等待定时器 信号量,互斥量

3.3 使用内核对象的线程间通信 线程可以使自己进入等待状态,直到一个对象变为已通知状态,这个功能通过等待函数完成。

3.4 事件 事件内核对象是最简单的对象。 当人工重置事件得到通知时,等待该事件的所有线程均变为可调度事件; 一个使用计数 一个布尔值,指明该事件是自动重置事件,还是人工重置事件; 一个布尔值,指明该事件是已通知状态,还是未通知状态。 当人工重置事件得到通知时,等待该事件的所有线程均变为可调度事件; 当自动重置事件得到通知时,等待该事件的线程中只有一个线程变为可调度线程。

3.4 事件 创建事件内核对象 当系统创建事件对象后,返回进程相关的事件对象的句柄。

3.4 事件 其它进程中的线程可以获得事件对象的访问权,方法: OpenEvent EVENT_ALL_ACCESS pszName参数中传递的值 使用继承性 使用DuplicateHandle函数来调用CreatEvent EVENT_ALL_ACCESS

3.4 事件 一旦事件已经创建,就可以直接控制它的状态 将事件设置为已通知状态 将事件设置为未通知状态

3.4 事件 事件的主要用途是标志事件的发生,并以此协调线程的执行顺序。 例子:用户在主线程输入命令,控制新建线程的运行。

3.5 互斥量 互斥量是一个种内核对象,确保线程拥有对单个资源的互斥访问权。 一个使用数量 一个线程ID 一个递归计数器 互斥量的行为特征与临界段相同,互斥量属于内核对象,而临界段属于用户方式对象。 互斥量的线程ID标识系统中哪个线程拥有互斥量,为0,没有线程拥有 递归计数器指明线程拥有互斥量的次数

3.5 互斥量 经常用于保护多个线程访问的内存块; 控制对共享资源的访问 保证每次只能有一个线程获得互斥量

3.5 互斥量 互斥量的创建 另一个进程可获得本进程相关的互斥量的句柄

3.5 互斥量 释放互斥量 等待互斥量 互斥量不同于其它内核对象,互斥对象有一个“线程所有权”的概念。

3.6 信号量 信号量是一个内核对象,可用来管理大量有限的系统资源 信号量使用规则: 一个使用计数 32位整数,最大资源数量 32位整数,当前资源数量 信号量使用规则: 当前资源数量大于0,则等待信号量的线程获得资源继续运行,当前资源数量减1 当前资源数量等于0,则等待信号量的线程继续等待,直到有线程释放信号量,使当前资源数量大于0

3.6 信号量 创建信号量 另一进程可获得与本进程相关的信号量的句柄

3.6 信号量 释放信号量 例,两个线程分别有一个初值为0的Int型局部变量,两个线程的行为是在一个循环中,使整型变量递增,一个约束条件,在递增过程中,这两个值的差不超过5

4. 调度优先级

4. 调度优先级 Windows是一个多任务多线程操作系统,调度方法是基于优先级的时间片轮转抢占式调度。 每个线程被赋予优先级号码:0~31 高优先级:优先调度,且可以即时调度,中断低优先级线程。 同优先级:时间片轮转法 低优先级:就绪状态,直到高优先级线程执行完毕。

1