Windows核心编程笔记(七) 线程调度 优先级 关联性
来源:互联网 发布:vb log无法识别 编辑:程序博客网 时间:2024/05/23 21:56
首先线程与系统时钟间隔参见http://blog.csdn.net/wangpengk7788/article/details/54287947
在抢占式多任务操作系统中,线程的运行是有限制的,系统会调度一个线程在一个时间块内占用CPU,在时间到了之后将线程的上下文(CONTEXT结构,保存线程切换前的CPU个寄存器的值)保存到线程内核对象中,从另一个可调度线程的CONTEXT中获取属于它的CPU各寄存器的值,设置CPU寄存器,执行该线程,这样重复着在不同的线程之间切换,保证每个可调度线程能得到执行时间。
在我使用的64位WIN7中 GetSystemTimeAdjustment
DWORD SuspendThread(HANDLE hThread ); 返回线程上次挂起的次数
挂起一个线程,一个线程最多可以挂起, 一个线程最多可以挂起MAXIMUM_SUSPEND_COUNT (127)次, 被挂起的线程不参与线程调度
DWORD ResumeThread(HANDLE hThread ); 返回上次挂起次数
递减线程内核对象中 线程挂起计数,只有在挂起减到0时,线程才能恢复运行
进程不能挂起,除了在调试器处理WaitForDebugEvent时,被调试的进程所有线程会挂起。
Sleep函数
1、调用Sleep函数使线程挂起,线程放弃剩余的时间片
2、Sleep设置的挂起时间只是近似值,不保证会准时醒来
3、可以传入INFINITE线程永久挂起
4、传入0表示放弃当前使用的剩余时间片
SwitchToThread 让出时间片,可能调度给比自己优先级低的线程
可以在一段代码的之前使用GetThreadTime获取线程执行的时间,取前后时间的差 做为该段代码的执行时耗。
在VISTA中为线程分配CPU时间的方式发生了变化 ,在新的系统中使用处理器时间戳计时器TSC,在线程被调度程序暂停时,将计算此时TSC的值与线程开始时的TSC值之间的差,然后在线程执行时间上加上该差值,不计算中断时间。我们可以使用ReadTimeStampCounter宏来获取TSC的值。
GetThreadContext 获取线程的上下文,这里CONTEXT结构对熟悉汇编的看起来会很亲切。Windwos 还是提供了SetThreadContext函数,这是很强大的对于喜欢做一些比较另类和猥琐的事情的人,比如可以创建一个挂起的进程比如系统的计算器,把另一个执行文件,比如系统的记事本程序自己加载到这个挂起的进程空间中去,然后改变主线程的CONTEXT,设置成记事本程序主线程入口所需要的环境,那么就可以借尸还魂了。在任务管理器里看到的是一个计算器程序,实际运行的代码是记事本的。
线程的优先级
在Windows中线程的优先级为0-31,优先级高的线程优先被调度,只有在优先级高的线程都处于不可调度状态时,才递减调度其次优先级的线程,当较高优先级的线程占用了CPU时间,致使较低优先级的线程无法运行时成为饥饿,在多处理器上饥饿的情况发生的可能性很小,系统大多数线程都是不可调度的,例如线程调用了GetMessage等待获取消息,如果这时消息队列中没有消息,系统会暂停这个线程,并将CPU分配给另一个等待调度的线程。
在较低优先级的线程被调度时,如果有较高优先级的线程已经处于可调度状态,系统会暂停较低优先级的线程,将CPU分给高优先级的线程,Windows的线程调度是抢占掠夺式的。
Windwos的进程优先级分为6个等级,可以通过SetPriorityClass来设置
BOOL WINAPI SetPriorityClass( __in HANDLE hProcess, __in DWORD dwPriorityClass);
dwPriorityClass对应的标志实际优先级值
优先级标志优先级值idle (低)IDLE_PRIORITY_CLASS4Below (低于标准)BELOW_NORMAL_PRIORITY_CLASS normal (标准)NORMAL_PRIORITY_CLASS7或9Above (高于标准)ABOVE_NORMAL_PRIORITY_CLASS high (高)HIGH_PRIORITY_CLASS13realtime (实时)REALTIME_PRIORITY_CLASS24
Windwos的线程有6个相对于进程的优先级,相对优先级使用 SetThreadPriority来设置
BOOL WINAPI SetThreadPriority( __in HANDLE hThread, __in int nPriority);
nPriority对应的标志在进程优先级的基础上调整
线程优先级等级标志优先级值idle (最低)THREAD_PRIORITY_IDLE如果进程优先级为realtime则调整为16,其它情况为1LOWEST 低THREAD_PRIORITY_LOWEST-2(在原有基础上-2)BELOW 低于标准THREAD_PRIORITY_BELOW_NORMAL-1(在原有基础上-1)NORMAL(标准)THREAD_PRIORITY_NORMAL不变(取进程优先级值)ABOVE 高于标准THREAD_PRIORITY_ABOVE_NORMAL+1(在原有基础上+1)HIGHEST(高)THREAD_PRIORITY_HIGHEST+2(在原有基础上+2)CRITICAL(最高)THREAD_PRIORITY_TIME_CRITICAL如果进程优先级为realtime则调整为31,其它情况为15这些进程优先级和线程相对优先级在Windwos不同版本 所对应的优先级值得映射不有变化的。
当一个进程中的线程为了响应某种IO事件,比如窗口消息,磁盘读取,获取网络包,线程会在这时被系统动态提升为NORMAL级,且只能提升1~15级的线程。在线程提升优先级后的每个时间片内优先级会被递减,直到恢复原来的优先级。
可以使用SetProcessPriority 来设置是否允许系统动态提升线程优先级。使用GetProcessPriority来获取线程是否开启被提升。
调度IO请求优先级
在设置进程和线程优先级时可以为 这两个函数传入 对应的THREAD_MODE_BACKGROUND_BEGIN PROCESS_MODE_BACKGROUND_BEGIN 让线程或进程进入低IO优先级状态,传入THREAD_MODE_BACKGROUND_END PROCESS_MODE_BACKGROUND_END 进入NORMAL级状态。
CPU关联性
我们可以使用下满两个函数设置线程或进程运行于哪个CPU之上。dwProcessAffinityMask 用二进制位做掩码,比如3 代码运行在CPU0和CPU1上,5表示在CPU2和CPU0上
BOOL WINAPI SetProcessAffinityMask( __in HANDLE hProcess, __in DWORD_PTR dwProcessAffinityMask);
DWORD_PTR WINAPI SetThreadAffinityMask( __in HANDLE hThread, __in DWORD_PTR dwThreadAffinityMask);
- Windows核心编程笔记(七) 线程调度 优先级 关联性
- 《Windows核心编程》读书笔记七 线程调度,优先级和关联性
- Windows核心编程--线程调度/优先级/关联性
- Windows核心编程(六)线程调度、优先级和关联性
- 《Windows核心编程》——七 线程调度、优先级和关联性
- windows 核心编程 (线程调度,优先级和关联性)
- 《Windows核心编程系列》谈谈线程调度、优先级和关联性
- windows核心编程-线程调度,优先级和关联性
- Windwos核心编程:(四)线程调度,优先级和关联性
- Windows核心编程 线程基础 线程调度、优先级、关联性 用户模式下的线程同步
- 《Windows核心编程》第7章 线程调度、优先级和关联性
- 《windows核心编程系列 》六谈谈线程调度、优先级和关联性
- 《windows核心编程系列 》六谈谈线程调度、优先级和关联性
- Windows核心编程笔记(5)----线程调度,优先级
- 七(1-5) 线程的调度、优先级和关联性
- 七、线程调度优先级和关联性
- 线程调度、优先级和关联性(7)
- 七 (7.8 线程优先级 - 7.11 关联性)
- MFC——“依米魔法邮箱”开发笔记
- 第9天(就业班) 课程回顾、http协议、http请求、http响应
- Ajax 如何提交集合到mvc后台
- WAMPServer: You don’t have permission to access /phpmyadmin on this server.
- 关于页面之间传递参数为中文问题
- Windows核心编程笔记(七) 线程调度 优先级 关联性
- Android 系列 6 图形用户界面 (GUI)
- VIJOS P1153 猫狗大战
- 程序员面试金典第二章:链表(5) 链式A+B
- 81. Search in Rotated Sorted Array II
- artDialog4.1.2 弹出层插件
- 应用部署到was8启动之后后台报错
- Android本地图片或者网络图片高斯模糊效果(毛玻璃效果)图片模糊效果一行代码搞定
- 创建Qt Quick项目