线程优先权Thread Priority概念总结

本文介绍了线程优先权的概念,包括为什么需要线程优先级、优先级的分类和层级,以及如何通过SetThreadPriority和GetThreadPriority函数设置和获取线程优先级。线程的优先级可以通过优先权类别、优先权层级和动态提升来确定。文章还讨论了线程的挂起和恢复,并提供了一个代码实例来演示这些概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

全文参考《WIN32多线程设计》一书。
为什么会有线程优先权:
为什么CPU处理线程时会按优先级执行?想象在忙碌的一天中,有很多事情待做但时间又不够,其中有很多紧急的事情。比如当晚的英语在线测试,明天的正式作业,下午重要的考试等等,你将如何安排一天的活动?如果这期间时想上厕所,或突然来电话了,你将如何选择?…是不是最重要的事最先做?这时候当然就要有个做事的主次顺序,这种处理事情的主次顺序反映在WIN32多线程中,则以0-31数值大小表示线程的重要程度,CPU以等待中的线程优先值最大的为目标决定下一个该执行哪条线程。对此,Windows实现了一个基于优先级的抢先式多处理及调度系统。

线程优先权概念:
Win32 有所谓的优先权( priority)观念,用以决定下一个获得 CPU 时间的线程是谁。较高优先权的线程必然获得较多的 CPU 时间

进程和线程的优先权:
Win32 优先权是以数值表现的,并以进程的“优先权类别( priorityclass)”线程的“优先权层级 ( priority level)”和操作系统当时采用的“动态提升( Dynamic Boost )”作为计算基准。 所有因素放在一起,最后获得一个 0~31 的数值。拥有最高优先权之线程,即为下一个将执行起来的线程。如果你有一大把 worker 线程,其“优先权类别”和“优先权层级”都相同,那么就每一个轮流执行。

优先权类别:
优先权类别”是进程的属性之一。这个属性可以表现出这一进程和其他
进程比较之下的重要性。 Win32 提供四种优先权类别,每一个类别对应一个基
本的优先权层级。

HIGH_PRIORITY_CLASS13
IDLE_PRIORITY_CLASS4
NORMAL_PRIORITY_CLASS7 or 8
REALTIME_PRIORITY_CLASS24

优先权层级:
线程的优先权层级( Priority Level )是对进程的优先权类别的一个修改,
使你能够调整同一个进程内的各线程的相对重要性。一共有七种优先权层级,

THREAD_PRIORITY_HIGHEST+2
THREAD_PRIORITY_ABOVE_NORMAL+1
THREAD_PRIORITY_NORMAL0
THREAD_PRIORITY_BELOW_NORMAL–1
THREAD_PRIORITY_LOWEST-2
THREAD_PRIORITY_IDLESet to 1
THREAD_PRIORITY_TIME_CRITICALSet 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;
}

执行结果:
在这里插入图片描述
实际执行顺序并不理想,这可能和很多因素有关,待深入理解学习后再尝试找出原因。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值