《Windows核心编程》读书心得——线程(线程调度)(4)

原创 2011年01月09日 16:59:00

 

 

l  CPU切换调度线程:

每个线程都有一个上下文(CONTEXT),保存在线程的内核对象中。它记录了线程上一次执行时CPU寄存器的状态。

大约每隔20ms,CPU会查看当前所有的线程,然后在可调度的线程中选择一个进行调度。CPU切换调度线程时,先将CPU寄存器写回线程上下文(这样,下次调度该线程,就能从上次停止的地方继续),停止运行原线程;检查剩下的可调度线程内核对象,选择另一个线程内核对象,将该线程上下文载入CPU寄存器。

 

查看和设置CONTEXT:

查看context:GetThreadContext()

设置context:SetThreadContext()

 

l  线程的挂起和恢复:

ResumeThread ():将挂起计数减1,当挂起计数为0,唤醒线程。

(若调用成功,返回线程的前一个挂起计数;否则,返回0xFFFFFFFF)

SuspendThread():将挂起计数加1,挂起线程。

Sleep():线程睡眠,让出时间来调度其他线程。

假如需要强制CPU停止调度当前线程,把时间片让给其他线程,可以使用Sleep(0)或SwitchToThread(),两者的区别如下:

Sleep():时间片只能让给优先级相同或更高的线程;

SwitchToThread():只要有可调度线程,即便优先级较低,也会让其调度。

 

l  两个从消息队列取消息的函数:

PeekMessage():从消息队列取一条消息,但不取走。

GetMessage():从消息队列取一条消息,并取走。

 

l  线程优先级:

优先级为0的线程:系统启动时,会创建一个优先级为0的“页面清零线程”,它只有在系统中没有其他可调度线程时,才能调度,用来清除内存中的闲置页面。

优先级在1 ~ 15之间的线程:一般用户模式下,线程的优先级都在该范围。

优先级在16 ~ 30之间的线程:一般是内核线程。

 

线程的抢占:

较高优先级的线程,总是会抢占较低优先级线程的处理时间。一般而言,较高优先级的线程大多数都是不可调度的,否则会长期占用CPU时间。

 

动态提升优先级:

如上文所述,线程都有一个基本优先级,其范围从0到31。线程的优先级一般保持在基本优先级附近,但不是固定的,因为系统可能在某些情况下暂时将该优先级提高。

例如:当系统检测到有线程处于饥饿状态3到4秒时,会暂时将该线程的优先级提升到15,并允许其执行两个时间片。当两个时间片执行完,会将其恢复到基本优先级。

(注意:系统只会提升优先级在1 ~ 15之间的线程,而且提升后优先级不会高于15,以防影响操作系统。同时,系统只能提升一个线程的优先级,而不能降低其优先级)

 

相关函数:

SetProcessPriorityBoost( …):是否允许对进程进行优先级提升;

SetThreadPriorityBoost( …):是否允许对线程进行优先级提升;

GetProcessPriorityBoost( …):当前是否启用进程优先级提升;

GetThreadPriorityBoost( …):当前是否启用线程优先级提升。

 

l  为线程指定CPU:

 

NUMA:

非统一内存访问计算机体系结构。由多个系统板组成,每个系统板都有自己的CPU和内存块。每个CPU可访问任何一块系统板的内存,但访问自己所在系统板的内存比较快,而访问其它板上内存特别慢。

 

为线程指定CPU的好处:

如上介绍的NUMA系统,应该指定一个进程中所有的线程运行在某块系统板上,这样才能保证该板上的CPU在调度这些线程时不会访问其它板上的内存,从而保证效率。此外,假如为线程分配固定的CPU,可以减少CPU时间片切换带来的时间开销,这在某些情况下也是有利于提高工作效率的。

 

相关函数:

SetProcessAffinityMask(HANDLE  hProcess, DWORD_PTR dwProcessAffinityMask):

(1)hProcess:要设置的进程。

(2)dwProcessAffinityMask:位掩码,表示可以在哪些CPU上运行。该参数每个二进制位表示一个CPU的状态,若某位为1,表示能在该位对应的CPU上运行本进程(例如,0x5表示可以在CUP0和CPU2上运行)。

 

GetProcessAffinityMask( …):返回进程关联性掩码。

 

SetThreadAffinityMask( …):设置线程关联性掩码。

 

SetThreadIdealProcessor( …):设置线程的理想CPU(该函数第二个参数是0 ~ 31/63之间的数,表示理想CPU的编号)。用该函数设定了理想CPU,那么系统会优先选择该CPU来运行线程,同时当该CPU繁忙时,允许让线程在其它空闲CPU上运行,这样做效率更高。

 

相关文章推荐

《Windows核心编程》读书心得——线程(线程调度)(4)

l  CPU切换调度线程:每个线程都有一个上下文(CONTEXT),保存在线程的内核对象中。它记录了线程上一次执行时CPU寄存器的状态。大约每隔20ms,CPU会查看当前所有的线程,然后在可调度的线程...

《Windows核心编程》读书心得——线程(线程同步)(4)

l  用户模式下的线程同步:Volatile类型:告诉编译器必须到内存取变量值,而不使用寄存器中的值。因为每个线程都有各自的寄存器,它们的寄存器中同一变量的值可能不一致。原子访问:指的是一个线程在访问...

WINDOWS核心编程学习心得--线程调度

 线程的主要有五种状态 1.新建状态:新创建了一个线程对象。 2.就绪状态:线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CP...

3.Windows核心编程-线程及线程调度

线程 与进程类似,线程也由两个组件组成: 一个是线程的内核对象,操作系统用它管理线程。内核对象还是系统用来存放线程统计信息的地方; 一个线程堆栈,用于维护线程执行时所需的所有函数参数和局部变量。 /...
  • bxsec
  • bxsec
  • 2017年07月28日 14:18
  • 155

《Windows核心编程》——八 用户模式下的线程调度

前言

《Windows核心编程》——七 线程调度、优先级和关联性

前言     每个线程都有一个上下文(CONTEXT),后者保存在线程的内核对象中。这个上下文反映了线程上一次执行时CPU寄存器的状态。大约每隔20ms,Windows都会查看所有当前存在的线程内核对...

Windows核心编程<读书笔记七>线程的调度、优先级以及亲缘性 【含有代码】

【文起】亲爱的,已经12月份了,相聚的日子已经很临近临近了。爱你蟹儿,加油 线程的调度、优先级以及亲缘性 1、  系统只调度可以调度的线程。如果线程的暂停次数大于1,说明该线程已经暂停运行,不会给...

使用Executor代替手动的线程调度(java并发编程读书笔记五)

不使用Executor线程池: 单线程:顺序的执行任务不能提供良好的吞吐量或者快速的响应性 每任务每线程:大量线程创建,销毁,线程间切换的开销巨大,高负载下容易崩溃 Executor是基于 生...
  • wbean
  • wbean
  • 2011年11月15日 10:30
  • 1147

Windows核心编程读书笔记2——线程(2)线程内幕

线程结构 如上一篇文章所述,系统创建线程时,会分配一个内核对象与线程栈。如下图 线程内核对象如左侧,其初始为 1、引用计数为2 2、挂起计数为1(此时线程无法运行) 3、退出代码为STILL_A...

Windows核心编程读书笔记1——线程(1)线程基础

在Windows系统中,进程更像一个容器,其功能的实现是靠线程完成的,即进程具有惰性。一个进程,至少拥有一个线程来执行任务。(进程第一个被创建的线程叫做主线程,其他的进程中的线程均为其子线程) 线...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:《Windows核心编程》读书心得——线程(线程调度)(4)
举报原因:
原因补充:

(最多只允许输入30个字)