《Win32多线程程序设计》–Jim Beveridge & Robert Wiener

Win32 优先权是以数值表现的,并以进程的“优先权类别(priority class)”线程的“优先权层级 (priority level)”和操作系统当时采用的“动态提升(Dynamic Boost)”作为计算基准。 所有因素放在一起,最后获得一个0~31 的数值。拥有最高优先权之线程,即为下一个将执行起来的线程。如果你有一大把 worker 线程,其“优先权类别”和“优先权层级”都相同,那么就每一个轮流执行。这是所谓的 “round robin” 调度方式。如果你有一个线程总是拥有最高优先权,那么它就永远获得 CPU 时间,别人都别玩了。这就是为什么必须明智而谨慎地使用优先权的原因。

优先权类别( Priority Class)

“优先权类别”是进程的属性之一。这个属性可以表现出这一进程和其他进程比较之下的重要性。

优先权类别(Priority Classes) 基础优先权值(base priority)
HIGH_PRIORITY_CLASS 13
IDLE_PRIORITY_CLASS 4
NORMAL_PRIORITY_CLASS 7 or 8(译注:有些资料上写 7 or 9)
REALTIME_PRIORITY_CLASS 24

大部分程序:使用 NORMAL_PRIORITY_CLASS 。少数情况下才会考虑使用其他类别。 
Task Manager:使用 HIGH_ PRIORITY_CLASS,所以即使其他程序处于非常忙碌的状态下,它也总是能够有所反应。 
屏幕保护程序(screen saver ):使用IDLE_PRIORITY_CLASS,只会在 CPU 绝对空闲的时候才执行。 
和时间有密切关系的程序:使用REALTIME_ PRIORITY_CLASS。可以使该进程甚至优于核心进程和设备驱动程序。这个优先权类别不应该用于标准 GUI 程序或甚至于典型的服务器程序。

优先权层级(Priority Level)

调整同一个进程内的各线程的相对重要性。

优先权层级(Priority Levels) 调整值
THREAD_PRIORITY_HIGHEST +2
THREAD_PRIORITY_ABOVE_NORMAL +1
THREAD_PRIORITY_NORMAL 0
THREAD_PRIORITY_BELOW_NORMAL –1
THREAD_PRIORITY_LOWEST –2
THREAD_PRIORITY_IDLE Set to 1
THREAD_PRIORITY_TIME_CRITICAL Set to 15

注意: 对于 REALTIME_PRIORITY_CLASS 的调整值,有点不同于上表所列。

BOOL SetThreadPriority(HANDLE hThread, int nPriority); 
int GetThreadPriority(HANDLE hThread);

动态提升( Dynamic Boost)

决定线程真正优先权的最后一个因素是其目前的动态提升值(Dynamic Boost)。所谓动态提升是对优先权的一种调整,使系统能够机动对待线程,以强化程序的可用性。

Windows系统中的“动态提升”被设定为最大:这使得拥有键盘焦点的程序(前台程序)的优先权得以提升 +2 。这个设定使得前台程序比后台程序获得较多的 CPU 时间,因此即使系统忙碌,前台程序还是容易保持其 UI 敏感度

一个进程的线程:只要线程获得键盘输入,该线程就得到一个 +5 的优先权调整值。这使得该线程有机会处理那个输入,并且提供立即的回应给用户。其他可能引起优先权动态提升的情况还包括鼠标消息、计时器消息等等。

任何一个线程(不限属于哪一个进程):那是在一个“等待状态”获得满足时发生的,例如有一个线程正在等待一个 mutex,当 Wait…() 返回时,该线程的优先权会获得动态提升。这样的提升意味着 critical sections 将尽可能地被快速处理,而等待时间将尽可能地缩短。

(示例:创建初始挂起线程,设置优先级后取消挂起执行)

#include <stdio.h>
#include <time.h>
#include <Windows.h> DWORD WINAPI Thread(void *arg) {
for (int i = ; i < ; i++) {
printf("Run #%d\n", (int)time(NULL));
Sleep();
}
return ;
} int main(void) {
HANDLE hThread = CreateThread(NULL, , Thread, NULL, CREATE_SUSPENDED, NULL); // 创建线程,挂起不执行
SetThreadPriority(hThread, THREAD_PRIORITY_IDLE); // 设置线程优先级 Sleep();
printf("resume hThread\n");
ResumeThread(hThread); // 3s后继续执行线程hThread Sleep();
printf("suspend hThread\n");
SuspendThread(hThread); // 3s后挂起不执行线程hThread Sleep();
printf("resume hThread\n");
ResumeThread(hThread); // 3s后继续执行线程hThread WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
return ;
}

参考链接:Win32线程——优先权

Win32线程——优先权的更多相关文章

  1. 第5章 不要让线程成为脱缰的野马(Keeping your Threads on Leash) ---线程优先权(Thread priority)

    有没有过这样的经验?你坐在你的车子里,目的地还在好几公里之遥,而时间已经很晚了.你拼命想告诉那些挡住你去路的人们,今天这个约会对你是多么多么重要,能不能请他们统统--呃--滚到马路外?很不幸,道路系统 ...

  2. win32线程池代码(WinApi/C++)

    win32线程池代码(WinApi/C++) 健壮, 高效,易用,易于扩, 可用于任何C++编译器 //说明, 这段代码我用了很久, 我删除了自动调整规模的代码(因为他还不成熟)/********** ...

  3. win32线程

    win32线程 一丶什么是线程 在windows中常听到的就是线程.多线程.啊什么的. 这里介绍一下什么是线程. 1.线程是附属在进程中的一个执行实体.简而言之就是执行代码的. 2.每个进程至少有一个 ...

  4. Win32 线程同步

    Win32 线程同步 ## Win32线程同步 ### 1. 原子锁 ### 2. 临界区 {全局变量} CRITICAL_SECTION CS = {0}; // 定义并初始化临界区结构体变量 {线 ...

  5. win32线程栈溢出问题 (一)

    一.什么是线程栈溢出 我们都知道,每一个win32线程都会开辟一个空间,用来临时存储线程执行时所调用的一系列函数的参数.返回地址和局部变量及其他上下文信息.这个空间就是线程的栈区.栈区的容量是有限的, ...

  6. Win32线程——等待另一个线程结束

    转载: https://blog.csdn.net/yss28/article/details/53646627 <Win32多线程程序设计>–Jim Beveridge & Ro ...

  7. C++ win32线程数上限

    hThread = CreateThread( NULL,  0,  WorkerFunction,  &threadParm,  0, &dwThreadID  ); 这样的创建方法 ...

  8. win32 线程通信初步

    // 线程通信机制.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #define NUM_THREADS 10 #include < ...

  9. Win32线程安全问题.同步函数

    线程安全问题.同步函数 一丶简介什么是线程安全 通过上面几讲.我们知道了线程怎么创建.线程切换的原理(CONTEXT结构) 每个线程在切换的时候都有自己的堆栈. 但是这样会有安全问题. 为什么?  我 ...

随机推荐

  1. tsung

    要做针对mongodb的压力测试,下了个tsung,看看他的策略是什么,目前定位ts_launcher.erl:do_launch({Intensity, MyHostName, PhaseId})- ...

  2. springboot项目部署到独立tomcat的爬坑集锦

    目录 集锦一:普通的springboot项目直接部署jar包 集锦二:springboot项目不能直接打war包部署 集锦三:因为tomcat版本问题导致的lombok插件报错:Invalid byt ...

  3. mysql根据时间查询日期的优化

    例如查询昨日新注册用户,写法有如下两种: EXPLAIN select * from chess_user u where DATE_FORMAT(u.register_time,'%Y-%m-%d' ...

  4. 十一 Pipe

    Java NIO 管道是2个线程之间的单向数据连接.Pipe有一个source通道和一个sink通道.数据会被写到sink通道,从source通道读取. 创建管道 通过Pipe.open()方法打开管 ...

  5. nodejs的get与post

    index.html <html> <body> <form action="/api/v1/records" method="post&q ...

  6. 原生JS编写getByClass、addClass、removeClass、hasClass

    前言: 年后换了工作,在现在的公司写交互主要使用JS原生:刚刚入门前端的时候写交互一直用的原生JS,虽然用的不怎么样.后来去之前的公司之后,leader主张把jQuery用好,JS原生自然就熟练了:一 ...

  7. 视差滚动-background-attachement

    之前项目中没有涉及到视觉滚动的网站,但是毕竟是一种常用的网站类别,不得不了解.实现方法很简单,做一下简单的分析... 概述:滚动视差是指多层背景以不同的速度移动,形成立体的运动效果,来带非常出色的视觉 ...

  8. ActiveMQ相关:

    MQ连接字符串:failover:tcp://127.0.0.1:61616 管理地址:http://localhost:8161/admin/

  9. VC中BSTR、Char*、CString和CComBSTR类型的转换

    原文:http://blog.csdn.net/wanghaihao_1/article/details/37498689 1.char*转换成CString 若将char*转换成CString,除了 ...

  10. 【Supervised Learning】支持向量机SVM (to explain Support Vector Machines (SVM) like I am a 5 year old )

    Support Vector Machines 引言 内核方法是模式分析中非常有用的算法,其中最著名的一个是支持向量机SVM 工程师在于合理使用你所拥有的toolkit 相关代码 sklearn-SV ...