C++系列 --- 低优先级的线程为什么会被先执行

一、线程的优先级

线程的优先级范围从0(最低)到31(最高)。当你产生线程时,并不是直接以数值制定某优先级,而是采用两个步骤。

第一个步骤是指定“优先级等级(Priority Class)”给进程,第二步骤是指定“相对优先级”给该进行的所有线程。其中的代码在CreateProcess的dwCreationFlags参数中指定。如果你不指定,系统默认给的是NORMAL_PRIORITY_CLASS,除非父进程是IDLE_PRIORITY_CLASS(那么子进程也会是IDLE_PRIORITY_CLASS)。

要改变线程的优先级,用如下函数:

BOOL SetThreadPriority(HANDLE hThread,int nPriority)

二、线程的优先级值

SetThreadPriority的参数:

THREAD_PRIORITY_IDLE                         空闲

THREAD_PRIORITY_LOWEST                   最低

THREAD_PRIORITY_BELOW_NORMAL    低于正常

THREAD_PRIORITY_NORMAL                    正常

THREAD_PRIORITY_ABOVE_NORMAL      高于正常

THREAD_PRIORITY_HIGHEST                    最高

THREAD_PRIORITY_TIME_CRITICAL         实时

 三、运行实例

#include <iostream>
#include <Windows.h>
using namespace std;

DWORD WINAPI ThreadIdle(LPVOID lpParam)
{
	int i = 0;
	while (i++ < 10)
	{
		printf("Idle线程正在运行\n");
	}

	return 0;
}

DWORD WINAPI ThreadNormal(LPVOID lpParam)
{
	int i = 0;
	while (i++ < 10)
	{
		printf("Normal线程正在运行\n");
	}

	return 0;
}


int main()
{
	DWORD ThreadId[2];
	HANDLE h[2];

	// 创建线程1,置其状态为挂起状态
	h[0] = ::CreateThread(NULL, 0, ThreadIdle, NULL, 
		CREATE_SUSPENDED, &ThreadId[0]);

	// 设置优先级与IDLE
	::SetThreadPriority(h[0], THREAD_PRIORITY_IDLE);

	// 唤醒线程
	::ResumeThread(h[0]);

	// 创建线程2
	h[1] = ::CreateThread(NULL, 0, ThreadNormal, NULL, 
		0, &ThreadId[1]);

	::WaitForMultipleObjects(
		2, // 表示我们要等待的线程的内核对象的数量
		h,
		TRUE,// 只有都完成了才能结束
		INFINITE
	);

	system("pause");
	return 0;
}

四、运行结果

执行结果1
执行结果1
执行结果1

为甚两次执行的结果并不一样,低优先级的线程为什么会比高优先级的线程先执行?? 

五、为什么低优先级的线程会比高优先级的线程先执行

 在我们的操作系统当中,我们操作系统内核调用了若干个线程指定序列,然后指令序列开始推进,指令序列的优先级叫做相对优先级概念。

什么叫做相对优先级?在我们实际的开发过程当中,我们可能听说过操作系统中一个非常重要的知识,那就是尽可能多的使用CPU,CPU使用的越多,那么就代表着CPU的计算任务越重,资源就可以得到充分的利用。

短作业优先,耗时短的任务越先让CPU执行,那么所有的作业,在任务完毕的时候,使得所有作业的平均等待时间最短。

看上去这是一个非常优化的算法,但是这样存在一个非常大的弊端,比如,作业来的很早,作业运行耗时很长,那么在它还没有运行之前来了一个比它运行时间段的任务进入CPU的就绪队列,那么CPU就会先推进那个耗时短的作业,这样就会造成公平性的丧失。

在Windows系统中,其实也考虑过这个问题,我们的优先级并不是绝对优先级,在绝大多数情况下用户态的优先级都是相对的,那么操作系统就会调度,这样就会造成Normal优先级与Idle优先并不是严格的按照高优先级先运行,低优先后运行。操作系统也考虑到了公平性与效率性的问题。

Idle线程优先于Normal线程调用,在我们的调度过程当中,我么现在的系统已经是多核的,不在像以前一样,只有一个单核,那么在多核的情况下,A核与B核这个假定,主线程可能是和某一个线程在A核当中,另一个线程分发到另一个空闲的核当中,那么这就会造成低优先级的线程先于高优先的线程调用。

优先级只是一个相对的概念,不要想当然的认为高优先级的线程一定会先于低优先级的线程调用。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值