首页 > 嵌入式软件 > WinCE

1 引言

本文引用地址: http://embed.21ic.com/software/wince/201806/64260.html

本文分析了Windows 系统的进程调度机制,并设计了一种基于Windows 操作系统内核驱动的多核CPU 线程管理方法,实现了一个基于Windows 内核驱动的线程管理服务系统,它能让用户根据每一个任务线程对CPU 资源的需要程度和对实时性的要求,在多核CPU上合理为线程分配CPU 核。


图1 Windows 内核调度结构体关系图

2 Windows 系统的进程调度方法分析

Windows NT 中的每一个进程都是EPROCESS 结构体。此结构体中除了进程的属性之外还引用了其它一些与实现进程紧密相关的结构体。例如,每个进程都有一个或几个线程,线程在系统中就是ETHREAD 结构体。简要描述一下存在于这个结构体中的主要的信息,这些信息都是由对内核函数的研究而得知的。首先,结构体中有KPROCESS 结构体,这个结构体中又有指向这些进程的内核线程(KTHREAD)链表的指针(分配地址空间),基优先级,在内核模式或是用户模式执行进程的线程的时间,处理器affini ty(掩码,定义了哪个处理器能执行进程的线程),时间片值。在ETHREAD 结构体中还存在着这样的信息:进程ID、父进程ID、进程映象名。

在E P R O C E S S 结构体中还有指向P E B 的指针。

ETHREAD 结构体还包含有创建时间和退出时间、进程ID 和指向EPROCESS 的指针,启动地址,I/O 请求链表和KTHREAD 结构体。在KTHREAD 中包含有以下信息:内核模式和用户模式线程的创建时间,指向内核堆栈基址和顶点的指针、指向服务表的指针、基优先级与当前优先级、指向APC 的指针和指向T E B 的指针。

KTHREAD 中包含有许多其它的数据,通过观察这些数据可以分析出KTHREAD 的结构。图1 描述了这些结构体之间的关系。

通过遍历KPROCESS 结构体中的ETHREAD,找到系统中当前所有的KTHREAD 结构,这个结构中的偏移量为0x124 处的Affinity 域(Windows XP sp3)即为设置CPU 亲缘性掩码的内存地址。在此重点解释CPU 亲缘性的概念,CPU 亲缘性就是指在系统中能够将一个或多个进程或线程绑定到一个或多个处理器上运行,这是期待已久的特性。也就是说:" 在1号处理器上一直运行该程序"或者是"在所有的处理器上运行这些程序,而不是在0 号处理器上运行"。然后, 调度器将遵循该规则,程序仅仅运行在允许的处理器上。在Windows 操作系统上,给程序员设定CPU 亲缘性的接口是用一个32 位的双字型数表示的, 它被称为亲缘性掩码(Affinity bitMask)。亲缘性掩码是一系列的二进制位,每一位代表一个CPU 单元是否可执行当前任务。例如一个在具有四个CPU 的PC 机上( 或四核CPU) ,亲缘性掩码的形式的二进制数如下式所示:

0000000000000000000000000000XXXXB

其中自右向左,每一位代表0 到31 号CPU是否可用,由于本机只有四个CPU, 所以只有前四个位可用,X 为1则代表当前任务可执行在此位代表的CPU 上,X 为0 则代表当前任务不可执行在此位代表的CPU 上, 例如:

00000000000000000000000000000010B

代表当前任务只能执行在1 号 CPU 上(CPU 下标记数从0 开始),又如0x00000004 代表当前任务只能执行在2 号CPU 上,0x00000003 代表当前任务可以运行在0号和1 号CPU 上。

Windows 的进程调度代码是在它的SySTem 进程下的,所以它不属于任何用户进程上下文。调度代码在适当的时机会切换进程上下文,这里的切换进程上下文是指进程环境的切换, 包括内存中的可执行程序, 提供程序运行的各种资源.进程拥有虚拟的地址空间,可执行代码, 数据, 对象句柄集, 环境变量, 基础优先级, 以及最大最小工作集等的切换。而Windows 最小的调度单位是线程, 只有线程才是真正的执行体,进程只是线程的容器。Windows 的调度程序在时间片到期,或有切换线程指令执行(如Sleep,KeWaitForSingleObject 等函数)时, 将会从进程线程队列中找到下一个要调度的线程执行体,并装入到KPCR(Kernel ' s Processor CONtr ol Re g i o n , 内核进程控制区域) 结构中,CPU 根据KPCR 结构中的KPRCB 结构执行线程执行体代码。而在多核CPU 下,当Windows 调度代码执行时,从当前要调度执行的KTHREAD 结构中取出Affinity,并与当前PC 机上的硬件配置数据中的CPU 掩码作与操作,结果写入到指定的CPU,例如双核CPU 的设备掩码为0x03,如果当前KTHREAD 里的Affinity 为0x01,那么0x01&0x03=0x01,这样执行体线程会被装入CPU1的KPRCB 结构中得以执行,调度程序不会把这个线程交给CPU2 去执行。此过程如图2 所示。这就是为线程选择指定CPU 核的原理。

图 2 Windows 内核亲缘性调度原理图。

那么控制线程在指定CPU 上运行的突破口就是修改Windows 内核结构体KTHREAD 下的Affinity 域。然而Windows 内核结构被放在虚拟内存线性地址的高2G(不同版本Windows 下也可能是1G)地址空间,用户模式下的应用程序是无法访问这段内存空间的,所以必须编写Windows 驱动程序,来访问Windows 内核内存空间, 这也是本文将要描述的重点。

3 线程管理服务系统

整个系统的结构如图3 所示。该系统由两大部分组成,分别是内核模式下的管理服务系统设备驱动程序,和用户模式下的管理服务系统应用程序。管理服务系统应用程序通过调用Win32 子系统API,向内核下的管理服务系统驱动程序传递IRP,内核收到IRP 后,跟据收到的IRP 的内部信息,执行相应的派遣函数,对相应内存进行读写,从而给管理服务系统应用程序提供可用的系统信息。


图3 管理系统总体结构图。

3.1 内核模式下读取系统信息

线程管理服务系统驱动程序中,读取系统信息的方法用到了微软没有公开文档的内核服务函数,ZwQuerySystemInformATIon,这个函数被封装在ntdll.dll模块中,通过链接ntdll.lib 可得到此函数地址。通过一个枚举量SystemProcessInformaTIon 来得到进程线程相关信息,填入到第二个输入参数SYSTEM_PROCESS_INFORMATION结构中, 这样就获得了当前系统关于进程线程的信息。

3.2 内核模式下枚举系统进程线程

SYSTEM_PROCESS_INFORMATION结构中存储了进程及其线程的所有相关信息,表1 列出了它的具体内容,包括结构内域的地址偏移, 数据类型和描述。

SYSTEM_PROCESS_INFORMATION的第一个DWORD型是下一个进程 SYSTEM_PROCESS_INFORMATION相对于当前结构地址的偏移量,可以通过地址偏移来遍历所有的进程结构,当遇到某一个进程结构的0 x 0 0 0 0 处的DWORD 型值为0 时,说明这个结构体是系统内最后一个结构体。线程管理服务在它的派遣函数中通过这种方式遍历所有进程,从中提取有用的信息,填入两个自定义结构体中。如图 4 所示,描述了一个具有两个线程的进程的数据结构,首先在MY_PROCESS_INFO 结构中填入进程的相关信息,然后根据此进程所有的线程数,向系统申请足够大的分页内存空间,PVOID 型指针指向的是第一个线程结构所在的地址空间,然后向线程结构体中_MY_THREAD_INFO 中填入线程信息,再由线程结构体中的PVOID 型指针指向第二个线程结构体所在的地址空间,以此类推,最后一个线程结构体的PVOID型指针指向NULL。这样一个过程描述了一个进程及其所属的所有线程的枚举过程,通过对所有进程的遍历,可以得到系统中的一个完整的进程线程表,存在一段分页内存中,这样在应用程序中便可以得到这些信息。

表1 SYSTEM_PROCESS_INFORMATION 结构


图4 进程线程的两种数据结构。

3.3 线程管理服务系统应用程序设计

进程管理服务系统应用程序是要通过调用Win 32子系统的API 函数DeviceIoControl 来向线程管理服务系统驱动程序发送IRP 的,然后在IRP 结束之后把驱动程序中读出的所有有用进程线程信息填入到指定的内存中。这样线程管理服务系统应用程序就可以根据所获得的系统信息句柄来对线程CPU 亲缘性属性进行设置。首先为DeviceIoControl 中的InputBuffer 申请一段内存空间传入给驱动程序,驱动程序读取内核空间进程线程信息写入到这段内存中,应用程序读到信息并显示给用户。

在系统中应用程序为每一个CPU 维护一个结构体,内容包括该CPU 是否运行实时线程,该CPU 上运行的线程数(如果是实时线程CPU线程数为1),以及在此CPU上运行的线程结构数组的首地址。系统通过对此CPU 结构数组的解析来对线程进行管理。并通过DeviceIoControl函数把设置后的CPU 结构交给驱动程序内核。

3.4 修改Windows 内核结构体

在驱动程序读回应用程序下用户的设置结果后,就需要按照用户的设定修改KTHREAD 下的Affinity 域的掩码值了。首先要找到KTHREAD 的线性内存空间,PsGetCurrentProcess()内核函数可以返回内核下当前进程空间的E P R O C E S S 结构。E P R O C E S S 结构下的ActiveProcessLinks 域是LIST_ENTRY 结构,通过它可以遍历所有的ETHREAD 结构,那么那到KTHREAD 下的Affinity 域就不难了,可以使用两个循环嵌套来得到所有线程的Affinity 域并将其值设为应用程序中用户的设定值。线程CPU 掩码就被成功的修改了。当CPU 被设定为运行实时线程的CPU 时,在它上面运行的线程只能是一个实时线程,这时的运行线程数被设定为1; 当CPU被设定为非实时线程的时候,上面有可能除了任务线程运行之外,还有Windows 系统进程下的线程。

4 软件使用及性能测试

4.1 驱动的加载及软件的使用

首先需要把本系统的驱动sys 文件加载到Windows的服务管理器中,加载成功后打开应用程序,用户可以通过应用程序中显示出的当前系统内的进程和线程进行选择,并在GUI 图形界面中对其CPU 占用率及CPU亲缘性进行设置。

4.2 设置 CPU 亲缘性测试

测试运行在双核CPU 的PC 机上,系统运行一个要测试的任务线程(任务线程为一个108 次加法运算),四个其它线程(为测试方便,设为while 循环线程),限定了循环线程的CPU 亲缘性掩码为0x0001,任务线程的CPU亲缘性为0x0002,这样任务线程与其它线程分别在两个核上运行,分别测试了任务线程单独运行,任务线程与其它线程不设定CPU 亲缘性,任务线程与其它线程设定CPU 亲缘性三种情况下下任务线程的运行总时间如表2 所示。

表2

从表2 分析, 设定任务线程的CPU 亲缘性与其它线程所占用的CPU 分开,真正意义上的实现了任务的异步执行,非常有效的提高了实时线程对CPU 资源的使用率。

5 结束语

本文分析了Windows 系统的内核进程线程调度表2CPU 亲缘性设定三种情况下任务线程运行时间表机制,并在此基础上设计了一种基于Windows 操作系统内核驱动的多核CPU 线程管理方法, 实现了这样一个软件系统。首先在Windows 内核层获取系统进程线程信息,然后再把信息传入应用层,由应用层上的应用程序根据获取的信息句柄,对进程进行操作,用户在图形界面下按照仿真任务对CPU 资源的不同需求,进行相应的设置,可以为指定线程设置CPU 亲缘性的功能。在一定程度上为Windows 系统下的任务合理地分配了CPU 资源,为对实时性要求较高的任务提供了一个可靠的运行环境。

换一批

延伸阅读

[真心话] 中国“芯”为何攥在美国人手上?中美两地从业IC多年一语道破

中国“芯”为何攥在美国人手上?中美两地从业IC多年一语道破

很“高兴”,最近的中兴事件能把原本十分低调的半导体集成电路行业,推到舆论的风口浪尖。作为一个在中美两地工作了八年的IC从业者,我谈谈自己的一些亲身经历和体会。......

关键字:中国芯 美国 中兴事件

[真心话] 身价816亿美元!扎克伯格有望超越巴菲特成全球第三富

身价816亿美元!扎克伯格有望超越巴菲特成全球第三富

Facebook股价今日升至202美元的历史新高。这让Facebook创始人扎克伯格的身价达到了816亿美元,有望成为全球第三富有的人。目前,扎克伯格的身价与巴菲特之间的差距已缩小至2900万美元。Facebook创始人扎克伯格身价周......

关键字:扎克伯格 巴菲特

[新鲜事] 康宁“大猩猩玻璃新对手!三星开发出可弯曲“摔不碎”屏幕

康宁“大猩猩玻璃新对手!三星开发出可弯曲“摔不碎”屏幕

北京时间7月26日晚间消息,三星今日宣布,近期研发出一种“不破碎”的柔性显示面板,预计很快用于智能手机和其他消费电子产品中。对于传统的智能手机屏幕,其上面通常被玻璃覆盖,因此容易开裂或破碎。而三......

关键字:三星 康宁 显示屏

[趣科技] 可以为手机充电的牛仔裤

可以为手机充电的牛仔裤

但是如果有一条神奇的既可以容纳你的手机,同时还可以给你的手机充电,让你出门在外,从此无忧,你会去购买这款神奇的牛仔裤吗?......

关键字:充电

[真心话] 电子工程师安身立命的八大看家本领,你学会了几个?

电子工程师安身立命的八大看家本领,你学会了几个?

作为一个电子工程师(electronic engineer)必备技能:抄板,焊板,画板,仿真,编程,调试,创意,坚持。八大技能,你几级了?......

关键字:电子工程师

[新鲜事] 谷歌上亿大奖空置11年无人领取!难道真的没人眼馋吗?

谷歌上亿大奖空置11年无人领取!难道真的没人眼馋吗?

Google在11年前为了激励民间航天业的发展,曾设立探月大奖赛,只要满足一定条件就可以领取高达3000万美元(约合人民币1.9亿)奖金,但是直到11年后大奖还是名花无主。......

关键字:谷歌 民间航天业
条评论

我 要 评 论

网友评论

大家都爱看

  • 扇出型晶圆级封装的优势和挑战!

    我们有能力创造一些能保持前代性能并且更好更小的电子设备,例如今天的可穿戴设备、智能手机或平板电脑,这是由于很多因素超过摩尔定律而快速发展,从而能够从底层的嵌入组件发展到今天把它们封…

    2018-03-29
  • Xilinx推出革命性的新型自适应计算产品

    自适应和智能计算的全球领先企业赛灵思公司(Xilinx, Inc.,(NASDAQ:XLNX)),近日宣布推出一款超越FPGA功能的突破性新型产品,名为ACAP(Adaptive Compute Acceleration Platform,自适应计算加速…

    2018-03-20
  • 赛普拉斯为树莓派3 B+ IoT单板计算机提供强大稳定的无

    先进嵌入式系统解决方案的领导者赛普拉斯(纳斯达克代码:CY)近日宣布其Wi-Fi®和蓝牙®combo解决方案为全新的树莓派 3 B+(Raspberry Pi 3Model B+)IoT单板计算机提供强大稳定的无线连接…

    2018-03-20
  • 观看直播领红包,SEED-A10加速卡助力人工智能

    随着云服务器、云计算的发展,大家对硬件加速的需求越来越多,但是随着设备功耗的上升、性能需求越来越高,常规加速设备以及开始不能满足需求,因此FPGA逐渐在硬件加速中找到了自己的位置,而艾…

    2018-03-19
  • 特朗普:博通不得以任何形式收购高通

    白宫周一(3月12日)晚发出声明,川普(特朗普)总统出于“国家安全”考量、禁止新加坡博通公司(Broadcom)收购美国高通公司(Qualcomm)。

    2018-03-14