全文参考《WIN32多线程设计》一书。
为什么会有线程优先权:
为什么CPU处理线程时会按优先级执行?想象在忙碌的一天中,有很多事情待做但时间又不够,其中有很多紧急的事情。比如当晚的英语在线测试,明天的正式作业,下午重要的考试等等,你将如何安排一天的活动?如果这期间时想上厕所,或突然来电话了,你将如何选择?…是不是最重要的事最先做?这时候当然就要有个做事的主次顺序,这种处理事情的主次顺序反映在WIN32多线程中,则以0-31数值大小表示线程的重要程度,CPU以等待中的线程优先值最大的为目标决定下一个该执行哪条线程。对此,Windows实现了一个基于优先级的抢先式多处理及调度系统。
线程优先权概念:
Win32 有所谓的优先权( priority)观念,用以决定下一个获得 CPU 时间的线程是谁。较高优先权的线程必然获得较多的 CPU 时间
进程和线程的优先权:
Win32 优先权是以数值表现的,并以进程的“优先权类别( priorityclass)”线程的“优先权层级 ( priority level)”和操作系统当时采用的“动态提升( Dynamic Boost )”作为计算基准。 所有因素放在一起,最后获得一个 0~31 的数值。拥有最高优先权之线程,即为下一个将执行起来的线程。如果你有一大把 worker 线程,其“优先权类别”和“优先权层级”都相同,那么就每一个轮流执行。
优先权类别:
优先权类别”是进程的属性之一。这个属性可以表现出这一进程和其他
进程比较之下的重要性。 Win32 提供四种优先权类别,每一个类别对应一个基
本的优先权层级。
HIGH_PRIORITY_CLASS | 13 |
---|
IDLE_PRIORITY_CLASS | 4 |
NORMAL_PRIORITY_CLASS | 7 or 8 |
REALTIME_PRIORITY_CLASS | 24 |
优先权层级:
线程的优先权层级( Priority Level )是对进程的优先权类别的一个修改,
使你能够调整同一个进程内的各线程的相对重要性。一共有七种优先权层级,
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 |
动态提升:
优先级应用注意操作系统采用的“动态提升”会影响线程的优先级,所以常常导致真真实执行的线程 顺序并非按照你设定的优先级顺序执行-------------------详情友情访问: Windows线程优先级提升策略
设置线程优先级函数:
BOOL SetThreadPriority(
HANDLE hThread,
int nPriority
);
获取线程优先级函数:
int GetThreadPriority(
HANDLE hThread
);
线程创建时挂起:
将第四个参数设置为 CREATE_SUSPENDED。
CreateThread(NULL,0,FUN,NULL,CREATE_SUSPENDED,NULL);
线程执行中挂起:
SuspendThread(hThread);
单个线程可以暂停若干次。如果一个线程暂停了3次,它必须恢复3次,然后它才可以被分配给一个CPU。
线程恢复:
挂起的线程需要用相应函数恢复。
DWORD ResumeThread(HANDLEhThread);
实例
写一段代码将以上提到的函数都用一下。
代码解释:创建7个线程,创建时挂起线程,设置7个不同的优先级,按下回车,依次打印线程自己的优先级,查看执行情况。
#include<windows.h>
#include<stdio.h>
HANDLE H[5],HE,H1,H16;
DWORD WINAPI FUN(LPVOID P)
{
int *l=(int *)P;
WaitForSingleObject(HE,INFINITE);
//获取线程优先级
switch (GetThreadPriority(H[*l+2]))
{
case THREAD_PRIORITY_TIME_CRITICAL:
{
printf("THREAD_PRIORITY_TIME_CRITICAL \t %d\n",*l);
}
break;
case THREAD_PRIORITY_HIGHEST:
{
printf("THREAD_PRIORITY_HIGHEST\t %d\n",*l);
}
break;
case THREAD_PRIORITY_ABOVE_NORMAL:
{
printf("THREAD_PRIORITY_ABOVE_NORMAL\t %d\n",*l);
}
break;
case THREAD_PRIORITY_NORMAL:
{
printf("THREAD_PRIORITY_NORMAL\t %d\n",*l);
}
break;
case THREAD_PRIORITY_BELOW_NORMAL:
{
printf("THREAD_PRIORITY_BELOW_NORMAL\t %d\n",*l);
}
break;
case THREAD_PRIORITY_LOWEST:
{
printf("THREAD_PRIORITY_LOWEST\t %d\n",*l);
}
break;
case THREAD_PRIORITY_IDLE:
{
printf("THREAD_PRIORITY_IDLE\t %d\n",*l);
}
break;
default:
printf("false\t%d\n",*l);
}
SetEvent(HE);
return 0;
}
int main()
{
int i,j[7];
j[5]=THREAD_PRIORITY_IDLE;
j[6]=THREAD_PRIORITY_TIME_CRITICAL; //数组初值初始化对应线程优先级
HE=CreateEvent(NULL,false, false ,NULL);
H1=CreateThread(NULL,0,FUN,&j[5],CREATE_SUSPENDED,NULL);//将优先级设定好存在数组中并传给对应线程
H16=CreateThread(NULL,0,FUN,&j[6],CREATE_SUSPENDED,NULL);
for(i=4;i>=0;i--)
{
j[i]=i-2;
H[i]=CreateThread(NULL,0,FUN,&j[i],CREATE_SUSPENDED,NULL);
}
for(i=0;i<5;i++)//关闭动态调整优先级
{
SetThreadPriorityBoost(H[i],false);
}
for(i=-2;i<3;i++) //正式调整优先级
{
SetThreadPriority(H[i+2],i);
}
SetThreadPriority(H1,THREAD_PRIORITY_IDLE);
SetThreadPriority(H16,THREAD_PRIORITY_TIME_CRITICAL);
ResumeThread(H1);
for(i=0;i<5;i++)//将挂起的线程恢复
{
ResumeThread(H[i]);
}
ResumeThread(H16);
getchar();
SetEvent(HE);
Sleep(INFINITE);
return 0;
}
执行结果:
实际执行顺序并不理想,这可能和很多因素有关,待深入理解学习后再尝试找出原因。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)