Windows核心编程——第7章 线程调度
来源:互联网 发布:公告管理系统源码 编辑:程序博客网 时间:2024/05/17 10:06
线程的挂起和恢复
调用CreateProcess或CreateThread函数时,系统将创建线程内核对象,并把挂起计数初始化为1,在线程初始化之后,CreateProcess或CreateThread函数将查看是否有CREATE_SUSPENDED标志传入,如果有函数会返回并让新的线程处于挂起状态,否则函数会将线程的挂起计数挂起计数减为0,线程将成为可调度的。
可以使用ResumeThread函数来恢复被挂起的线程,使其重新成为可以调度的线程,使用SuspendThread函数将一个线程挂起。而在调试状态下可以使用WaitForDebugEvent来挂起进程中所有线程,使用ContinueDebugEvent来恢复进程中的线程。
OpenThread函数通过线程ID来返回其句柄,并使内核对象的使用计数递增1。
Sleep函数将使线程自己挂起一定长的时间,时间长度由参数决定,但是只是大约这么久,调用Sleep并传递参数INFINITE将导致系统永远不要调用这个进程,而传入参数0将告诉系统主调线程放弃时间片剩余部分,系统将重新选择线程执行,也可以继续执行Sleep这个线程。
SwichToThread函数调用时,系统查看是否存在急需CPU时间的饥饿线程,如果没有的话,SwichToThread将立即返回,如果存在的话,SwichToThread将调度该线程,运行一个时间片之后系统调度程序恢复正常运行。与Sleep(0)类似,差别就在SwichToThread允许执行低优先级线程,而Sleep会立即重新调度主调线程。
GetThreadTimes可以获得线程的系统时间信息,下面这个函数可以确定执行一个复杂算法所需要的时间。
GetProcessTimes可以获得进程的系统时间信息,返回的时间适用于一个指定进程中的所有线程,所返回的内核时间是所有线程在内核模式下所耗时间总和。
线程上下文CONTEXT结构分为几部分
l CONTEXT_CONTROL包含CPU的控制寄存器
l CONTEXT_INTEGER标识CPU整数寄存器
l CONTEXT_FLOATING_POINT标识CPU的浮点寄存器
l CONTEXT_SEGMENTS标识CPU的段寄存器
l CONTEXT_DEBUG_REGISTERS标识CPU的调试寄存器
l CONTEXT_EXTENDED_REGISTERS标识CPU的扩展寄存器。
l CONTEXT_FULL被定义为CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS
使用GetThreadContext函数可以获得一个CONTEXT结构,但是传给GetThreadContext之前需要使用上面的标志初始化ContextFlags,并且执行之前要使用SuspendThread挂起线程,GetThreadContext将返回用户模式线程上下文。
使用SetThreadCOntext函数可以将一个上下文CONTEXT结构的内容写回线程内核对象中,但是使用这个函数进也应该初始化标志ContextFlags,并且暂停线程,否则结果无法预料。
进程和线程优先级
每个线程都被赋予0~31的优先级数,系统确定要分配CPU时,会首先查看优先级31的线程,并以循环的方式进行调度,每次都会从最高的优先级调度开始。
系统启动的时候会创建一个名为页面清零线程的特殊线程。这个线程优先级为0,是整个系统中的一个优先级为0的线程,在没有其它进程需要执行的时候,将系统内存中的所有闲置页面清零。
进程优先级可以在调用CreateProcess时在fdwCreate参数中传入 需要的优先级,改变进程的优先级可以使用SetPriorityClass函数,获取进程优先级函数GetPriorityClass,使用SetThreadPriority来改变一个线程的相对优先级,使用GetThreadPriority来获得线程的相对优先级,如果想创建优先级非normal的新线程,需要先挂起线程,再SetThreadPriority设置线程的优先级,接着调用ResumeThread使线程成为可调度的。
SetProcessPriorityBoost允许或禁止系统提升一个进程中所有线程的优先级,如果想对进程中的某个线程进行设置,则可以使用SetProcessPriorityBoost函数,它可以允许或禁止提升某个线程的优先级。
SetFileInformationByHandle函数可以设置文件I/O请求权限,另外我们开发程序的时候应该尽量避免优先级逆转,尽量减少在normal和后台优先级线程之间使用共享同步对象,或者尽量不共享,以避免normal优先级线程因为后台优先级毛线拥有的锁而被阻塞,导致优先级逆转。
应用GetSystemInfo来查询机器上CPU的数量,使用SetProcessAffinityMask来设置进程的关联性,使用GetProcessAffinityMask来返回进程的关联性掩码。如果要进行更细粒度的设置的话,可以使用SetThreadAffinityMask来对线程关联性进行设置,但是设置线程的硬关联将影响调度程序的调度方案,所以要给线程设置一个理想的空闲的CPU,可以使用函数SetThreadIdealProcessor来实现。
- Windows核心编程——第7章 线程调度
- 《Windows核心编程》第7章 线程调度、优先级和关联性
- windows核心编程第七章--线程调度
- Windows核心编程:线程调度
- Windows核心编程——第6章 线程基础
- Windows核心编程学习笔记 第二部分 完成编程任务 第7章 线程的调度 优先级 亲缘性
- 核心编程随笔7——线程调度和优先级
- 《Windows核心编程》读书心得——线程(线程调度)(4)
- 《Windows核心编程》读书心得——线程(线程调度)(4)
- WINDOWS核心编程学习心得--线程调度
- Windows核心编程--线程调度/优先级/关联性
- 《Windows核心编程》——七 线程调度、优先级和关联性
- 《Windows核心编程》——八 用户模式下的线程调度
- Windows核心编程——第8章 用户模式下的线程同步
- 3.Windows核心编程-线程及线程调度
- 《Windows核心编程》第6章 线程基础
- Windows核心编程 第6章线程基础
- windows核心编程读书摘抄之第6章 线程
- js 设计模式 第十四章 Proxy Pattern
- codeforces 238A
- MyEclipse Servlet 模板修改
- HTML文档对象的事件及JS函数解析
- MFC札记
- Windows核心编程——第7章 线程调度
- BMP文件格式详解(BMP file format)
- 什么是网站流量?
- 如何使用gdb调试C程序
- Linux 下zip包的压缩与解压
- 一些简单的批处理脚本记录
- 【Android学习专题】控件组件篇:Dialog汇总
- Spring加载一些配置文件中不存在的bean,如DB2,SYBASE,Derby,H2等等,Error while extracting database product name
- 在两种不同的颜色中间,按阶数进行过渡