Windows线程:调度、优先级、cpu关联性

线程调度

线程的挂起和恢复

在线程的内核对象中有一个值表示线程的挂起计数,创建线程时挂起计数初始化为1,就不会进行CPU调度,当挂起计数为0,线程就成为可调度。

DWORD ResumeThread(HANDLE hThread);	//改变线程为可调度

成功返回:前一个挂起的计数
失败返回:0xFFFFFFFF

DWORD SuspendThread(HANDLE hThread);	//挂起线程

挂起多少次,必须恢复多少次,系统才会为该线程分配CPU
挂起+1,恢复-1,当挂起计数值为0时,才会调度

睡眠

当不需要调度时,可以调用:

VOID Sleep (DWORD dwMilliseconds);
将线程挂起dwMilliseconds长的时间(单位为毫秒,INFINITE为永远不要进行调度)

超线程(Xeon):Pentium4和更新的1CPU支持的一种技术,超线程处理器芯片有多个“逻辑”CPU,每个都可以运行一个线程,每个线程都有自己的体系结构状态。

线程的执行时间

BOOL GetThreadTimes();
//高精度计时
BOOL QueryPerformanceFrequency(LARGE_INTEGER* pliFrequency);
BOOL QueryPerformanceCounter(LARGE_INTEGER* pliCount);

线程优先级

调度程序在分配CPU时,是根据可调度优先级进行调度线程执行的。
每个线程被赋予0(最低)~31(最高)优先级,以循环的方式从31到0进行查找线程。
当高优先级的线程占用CPU,致使低优先级线程无法运行,这种情况称为饥饿。多处理器机器上的饥饿发生的可能性要小的多。
问题:Windows为抢占式,当低优先级执行时,有高优先级的线程就绪,就会暂停低优先级执行高优先级的线程。

进程永远无法调度,能调度的是线程,进程只是Microsoft提出的一个抽象概念,一般而言高优先级的线程很少调度,因为它们能很快得到CPU,相反,优先级低的应保持可调度状态,使用大量CPU时间。

线程优先级

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

线程在创建时,优先级被设置为normal,创建后可以进行改变

//设置线程优先级
BOOL SetThreadPriority(
	HANDLE hThread,	//线程句柄
	int nPriority);			//相对线程优先级
//获取线程的相对优先级
int GetThreadPriority(HANDLE hThread);
//首先创建挂起,修改后启动线程,再关闭线程句柄
DWORD dwThreadID;
HANDLE hThread = CreateThread(NULL,0,ThreadFunc,NULL,
	CREATE_SUSPENDED,&dwThreadID);
	SetThreadPriority(hThread,THREAD_PRIORITY_IDLE);
	ResumeThread(hThread);
	CloseHandle(hThread);

关联性

关联性大概的意思指与硬件的关联
线程在上一次运行的处理器上运行,让线程始终在同一个处理器上运行有助于重用仍在处理器高速缓存中的数据

NUMA(非统一内存访问)的计算机体系结构:由多个系统板组成,每个系统板都有自己的CPU和内存板块。
Windows Vista 允许我们设置进程和线程的关联性,可以控制线程与CPU的硬关联。

//获取计算机CPU数量:
GetSystemInfo();
//限制线程只能在固定CPU上运行:
BOOL SetThreadAffinityMask(
	HANDLE hThread,	//线程句柄
	DWORD_PTR dwThreadAffinityMask);	//指定CPU
例如:
SetThreadAffinityMask(hThread1,0x00000001);
//灵活使用CPU函数,分配CPU后可以灵活调整:
DWORD SetThreadIdealProcessor(
	HANDLE hThread,		//线程句柄
	DWORD dwIdealProcessor);		//一般传入MAXIMUM_PROCESSORS,表示线程没有理想的CPU使用

猜你喜欢

转载自blog.csdn.net/qq_42856154/article/details/90752445
今日推荐