深入理解操作系统原理之Windows进程管理

一、Windows 2000的基元成分

对象、进程、线程是Windows2000三个基元成份,它们之间有互相交叉的关系。

1、对象

对象是一个抽象的数据结构,在Windows2000中用以表示广义的资源。它是构成OS的三个基元成份中非活动的成份,对象是数据和有关操作的封装体,它包装数据、数据的属性以及可以施加于数据的操作等三个成份。具有相同特性的对象也可归为一个对象类,在软件设计中定义了对象类(称为类Class),而对象则是对象类一个具体实现的示例。对象作为抽象数据而封装在其内部的操作函数所提供的操作也给人活动成份的感觉,但是从操作系统这一角度来认识,对象是构成操作系统的非活动成份。而进程和线程则是构成OS的两个活动成份。

Windows 2000中的实体,当数据或资源对用户态开放时,或者当数据访问是共享的或受限制时,才使用对象。采用对象方法表示的实体有文件、进程、线程、信号量、互斥量、事件、计时器等。Windows 2000通过对象管理器以一致的方法创建和管理所有的对象类型,对象管理器代表应用程序负责创建和删除对象,并负责授权访问对象的数据和服务。
这里写图片描述
每一个对象都有一个对象头和一个对象体。对象管理器控制对象头,各执行体组件控制它们自己创建的对象类型的对象体。当进程通过名称来创建或打开一个对象时,它会收到一个代表进程访问对象的句柄。所有用户态进程只有获得了对象句柄之后才可以使用这个对象。句柄作为系统资源的间接指针来使用,这种不直接的方式阻止了应用程序对系统数据结构直接地随便操作。

2、进程

Windows2000中进程被定义为表示OS所要做的工作,是OS用于组织其必须完成诸工作的一种手段。NT中的进程由一个可执行的程序、一个私用的虚地址空间、系统资源和至少一个执行线程等四部分组成。
这里写图片描述
NT的进程概念与传统OS进程概念有所不同,NT进程是作为对象来实现,因此从广义角度来说,进程也是共享的资源(多个用户进程可共享服务器进程提供的服务)。

NT定义了一个进程对象类,进程的对象类的对象体和所包含的属性定义了进程对象的数据及其属性和施加其上的操作(服务),但描述进程组成的两个主要部分:进程地址空间和局限于进程的对象表,不包含在属性表中,因为它是附属的、不可见的。NT进程要求一个独特的组成成分:至少一个执行线程,这在传统OS中是没有的。NT进程的组成中没有进程控制块,有关进程的信息在进程对象的对象体中以及局限于进程的对象表中。
这里写图片描述

3、线程

NT的线程是进程内的一个执行单元,是进程内的一个可调度实体。一个线程是由唯一的标识符客户ID、描述处理器状态的一组状态寄存器的内容、用户栈和核心栈、一个私用存贮器等四部分组成,线程也是作为对象来实现。每个进程创建时只有一个线程,需要时这个线程创建其它线程。线性是进程的一个组成部分,一个NT进程可以有多个线程在其地址空间内执行。资源分配的单位是进程,调度和执行的基本单位是线程。
这里写图片描述

二、Windows进程控制API函数

1、CreateProcess函数

当一个线程调用CreateProcess时,系统就会创建一个进程内核对象,为新进程创建一个虚拟地址空间,并将可执行文件加载到该进程的地址空间中。然后系统再为新进程的主线程创建一个线程内核对象。通过执行启动代码,该主线程便开始运行,它最终调用WinMain、wWinMain、main或wmain函数。如果系统成功地创建了新进程和主线程,该函数便返回TRUE。

2、CreateThread函数

CreateThread函数创建一个在调用进程的地址空间中执行的线程。
格式:

HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD  dwStacksize, LPTHREAD_START_ROUTINE lpStartAddress, 
LPVOID tpParameter, DWORD dwCreationFlags, LPDWORD lpThreadld);

lpThreadAttributes:指向一个SECURITY_ATTRIBUTES结构,该结构决定了返回的句柄是否可被子进程继承。若lpThreadAttributes为NULL,则句柄不能被继承。
dwStackSize:定义原始堆栈提交时的大小(按字节计)。系统将该值舍入为最近的页。若该值为0,或小于默认时提交的大小,默认情况是使用与调用线程同样的大小。
lpStartAddress:指向一个新线程执行的LPTHREAD_START_ROUTINE类型应用定义的函数。该指针还表示远程进程中线程的起始地址。该函数必须存在于远程进程中。
lpParameter:定义一个传递给该新线程的32位值。
dwCreationFiags:定义控制线程创建的附加标志。若定义了CREATE_SUSPENDED标志,线程创建时处于挂起状态,并且直到ResumeThread函数调用时才能运行。若该值为0,则该线程在创建后立即执行。
lpThreadId:指向一个32位值,它接收该线程的标识符。
返回值:若函数调用成功,返回值为新线程的句柄;若函数调用失败, 返回值为NULL。

3、ExitThread函数

ExitThread函数结束一个线程。
格式:

VOID ExitThread ( DWORD dwExitCode ) ;

dwExitCode:定义调用线程的退出代码。使用GetExitCodeThread函数来检测一个线程的退出代码。
返回值:无。
SuspendThread()函数用于挂起指定的线程。
ResumeThread()函数递减指定线程的挂起计数,挂起计数为0时,线程恢复执行。

4、互斥对象函数

在windows2000中提供了互斥对象、信号量对象和事件对象等同步对象和相应的系统调用,用于进程和线程的同步。这些同步对象都有一个用户指定的对象名称,不同进程用同样的对象名称来创建或打开对象,从而获得该对象在本进程的句柄。
互斥对象(Mutex)就是互斥信号量,在一个时刻只能被一个线程使用,它用于进程、线程间的互斥。它的相关API函数包括:CreateMutex、OpenMutex和ReleaseMutex。

  • CreateMutex
    函数创建一个互斥对象,返回对象句柄。
  • OpenMutex
    函数为现有的一个已命名互斥体对象创建一个新句柄。
  • ReleaseMurex
    函数放弃指定互斥对象的所有权。

5、信号量对象函数

信号量对象(semaphore)就是资源信号量,初始值的取值在0到指定最大值之间,用于限制并发访问的线程数,也可用于进程、线程间的同步。它的相关API包括:CreateSemaphore、OpenSemaphore和ReleaseSemaphore。

  • CreateSemapore
    函数是创建一个有名或者无名信号量对象在输人参数中指定最大值和初值,返回对象句柄。
  • OpenSemaphore
    函数为现有的一个已命名信号机对象创建一个新句柄。
  • ReleaseSemaphore
    函数释放对信号量对象的占用,将指定信号对象的计数增加一个指定的数量。

6、等待操作函数

Windows 2000为对象提供了两个统一的等待操作函数WaitForSingleObjectWaitForMultipleObjiects。等待的对象包括:Change notification(改变通告);Console input(控制台输入);Event(事件);Job(作业);Mutex(互斥对象);Process(进程);Semaphore(信号量);Thread(线程);Waitable timer(可等待定时器)。函数决定等待条件是否被满足。如果等待条件并没有被满足,调用线程进入一个高效的等待状态,当等待满足条件时占用非常少的处理器时间。在运行前,一个等待函数修改同步对象类型的状态。修改仅发生在引起函数返回的对象身上。例如,信号的计数减1。一个线程通过调用等待函数拥有对象。创建该对象的线程也拥有对象,而不需要调用等待函数。

7、临界区对象函数

临界区对象只能用于在同一个进程内使用的临界区,同一个进程内各线程对它的访问是互斥进行的。把变量说明为CRITICAL_SECTION类型,就可作临界区使用。相关的API包括InitializeCriticalSection、EnterCriticalSection、TryEnterCriticalSection、LeaveCriticalSection和DeleteCriticalSection。

  • InitializeCriticalSection
    函数初始化临界区对象。
  • EnterCriticalSection
    函数是等待指定临界区对象的所有权。当调用线程被赋予所有权时,该函数返回。
  • TryEnterCriticalSection
    函数决不允许调用线程进入等待状态。它的返回值能够指明调用线程是否能够获得对资源的访问权。TryEnterCriticalSection发现该资源已经被另一个线程访问,它就返回FALSE。在其他所有情况下,它均返回TRUE。运用这个函数,线程能够迅速查看它是否可以访问某个共享资源,如果不能访问,那么它可以继续执行某些其他操作,而不必进行等待。
  • LeaveCriticalSection
    函数释放指定临界区对象的所有权
  • DeleteCriticalSection
    函数释放与临界区对象相关的所有系统资源。

三、Windows 2000内部进程通信机制

1、本地过程调用LPC

Windows 2000的客户进程与服务器进程之间的通信采用消息传送,而消息传送必须经过执行体的本地过程调用LPC。LPC是一个用于高速信息传输的进程间的通信机构,LPC是一个灵活的、经过优化的“远程过程调用”(RPC)版本,(RPC是一种通过网络在客户与服务器进程之间传递信息的工业标准通信机制),在Win32 API下它是不可用的,它是一个只对Window 2000操作系统组件有效的内部机制。LPC被使用在一个服务器进程与该服务器的一个或多个客户进程之间。LPC提供了三种不同的消息传送方法:

第一种方法适用于传送小于256B的消息。它将消息传给与服务器进程相连的端口对象,系统为每个端口对象设置有一个固定大小的消息队列,作为通信之用,此方法用于发送少于256字节的信息。这个方法类同于消息缓冲队列通信机制。

第二种方法适用于传送大于256B的消息。它将消息指针传给与服务器进程相连的端口对象,并把消息存放在共享的主存区域中,消息大小受进程所分得的主存配额限制。消息传送的过程如下:当客户要传送大消息时,就由它自己创建一个称为主存区域的对象-主存共享的对象,LPC机制使得该地址空间为客户进程和服务器均可见,然后客户进程把大消息存放在该主存区域对象中;再向服务的的端口对象的消息队列中传送一个小消息指出所传送消息的大小和消息所在的地址指针。

第三种方法适用于服务器想读或写大量数据而共享区又太小情况。数据可以直接从客户地址空间读出或向客户地址间写入。LPC组件提供了两个函数,服务器可以用它们来完成这些操作,以第一种方法发送的消息被用于同步正在传送的信息。

LPC典型地应用于以下情况:服务器创建已命名的服务器直接端口对象。客户提出与这个端口连接的请求。如果同意该请求,客户通信端口和服务器通信端口就会被创建。客户得到客户通信端口的句柄,服务器得到服务器通信端口句柄。然后客户和服务器将为了它们之间的通信使用新的端口。

2、多级反馈队列调度算法

Windows2000采用可抢占动态优先级多级反馈就绪队列调度算法,Windows2000的调度单位是线程。2000执行体支持32级优先级,并将它们分成两类,实时优先级(16-31)和可变优先级(1-15),0级为系统保留,运行一个仅用于对系统中空闲物理页面进行清页的零页线程。每个优先级一个就绪队列,高序号队列为高优先级。实时优先级采用多级队列调度算法;可变优先级采用多级反馈队列调度算法,每个线程优先级变化范围是5级,可变优先级又分为高级、中上、中级、中下和空闲五类。
这里写图片描述

线程完整用完一个规定的时间片值时,重新赋予新时间片值时,优先级降一级(不低于基本优先级),放在相应优先级就绪队列的尾部;
这里写图片描述

线程由于调用等待函数而阻塞时,减少一个时间片,并依据等待事件类型提高优先级;如等待键盘事件比等待磁盘事件的提高幅度大。
这里写图片描述
在下列5种情况下,Windows 2000会提升线程的当前优先级:

  • I/O操作完成
  • 信号量或事件等待结束
  • 前台进程中的线程完成一个等待操作
  • 由于窗口活动而唤醒图形用户接口线程
  • 线程处于就绪状态超过一定时间,但没能进入运行状态(处理机饥饿)

线程优先级提升的目的是改进系统吞吐量、响应时间等整体特征,解决线程调度策略中潜在的不公正性。但它也不是完美的,它并不会使所有应用都受益。Windows 2000永远不会提升实时优先级范围内(16至31)的线程优先级。

四、操作系统结构设计

1、操作系统采用结构程序设计的必要性

由于操作系统日趋庞大,结构日益复杂,错误增加以至不可避免。在以后每个新版中都纠错。其次由于操作系统存在并发性,进程间执行序列数量巨大,推进序列不确定性,程序错误的某种表现形式不重复出现,可能使人误解为一次偶然性机器的故障。这给操作系统调试带来了困难。为了使操作系统高可靠、高效能、可理解和可修改,操作系统必须采用结构程序设计方法。

2、模块接口法

模块接口法是OS最早采用的一种结构程序设计方法,早期操作系统(IBM的OS)和小型OS(如MS-DOS)均属此类型。模块接口法把一个系统按功能分成若干个具有一定独立性和大小完成某方面功能的模块,并规定好各模块之间的接口。接着在明确每个模块的内部功能的基础上对它们进行独立设计。最后在各模块设计完成后按照模块间的接口关系,将所有模块逐步链接成一个大系统。

模块接口法的优点是使OS设计实现模块化的基本结构程序设计方法,它增加了OS灵活性,便于修改和维护。但由于模块部接口复杂,使得系统的结构关系不清晰,因而使系统的可靠性降低。故又称模块接口法为无序模块法。

3、层次结构法

为了减少各模块之间无序调动、互相依赖关系,特别是清除循环现象,引入层次结构设计法。它将模块间无序调用变为有序调用,它把OS的所有功能模块,按功能流图的调用次序,排列成若干层,各层之间的模块只能是单向调用关系,即是只允许上层模块调用相邻下层模块。这样操作系统的结构清晰,而不构成循环,使系统的调试和验证变得容易。

层次结构法采用自底向上法形成操作系统。它先在裸机上添加第一层精心编制的软件,形成比原来机器功能更强的机器,称为虚拟机A1。再经过几乎是穷尽无遗的测试后,就有较大把握确信虚拟机A1是正确的。然后,再在A1上增加一层精心编制的软件,形成功能更强、更接近于实际要求的虚拟机A2,再经过几乎是穷尽无遗的测试, …… ……如此一层一层地自底向上地铺设各软件层,每一层都实现若干功能,最后构成满足要求的虚拟机An。因此只要下层各模块设计是正确的,就为上层功能模块的设计提供了可靠基础,从而增加了系统的可靠性。

1968年Dijkstra在ELX8机器上编制的操作系统THE中采用各层间单向依赖,层内各模块互相独立的全序的层次关系设计。但该系统通信开销大,系统经过层层调用效率低,该设计方法不适用大型OS。在大层OS中要建立一个全序的层次结构关系是十分困难,往往无法避免循环现象。因些层次结构设计应作为OS设计的原则,尽可能将操作系统各功能模块排成有序层次,以便尽量减少系统中循环现象。

4、客户-服务器方式

操作系统结构技术的发展是与整个计算机技术的发展相联系的。当前技术发展的突出特点是要求广泛的信息和其它资源的共享,这一要求促使网络技术的普遍应用和发展。由于网络技术逐渐成熟,并实用化,再加以数据库联网已是应用的新趋势,为用户提供一个符合企业信息处理应用要求的分布式处理的系统环境是应用潮流的需要。操作系统采用客户/服务器结构,它将非常适应于分布式处理的计算机环境中,所以说C/S模式是第三代操作系统。

客户/服务器C/S结构的思想是把操作系统分成内核和若干个进程。内核运行在核心态,负责调度、原语操作和中断处理等操作系统基本功能。每个进程实现单个的一套服务(例如:主存服务、进程生成服务等),称为服务器进程。每个服务运行在用户态,它执行一个循环以检查是否有客户已请求某项服务。而客户可以是另外的操作系统成分,也可以是应用程序。客户通过发送一个消息给服务器进程来请求提供一项服务。操作系统内核把该消息传送给服务器进程,而后该服务器执行有关的操作,操作完成后,内核用另一个消息把结果返回给客户进程。C/S结构模式的操作系统有卡内基.梅隆大学研制的Mach 操作系统和美国微软公司研制的WindowsNT操作系统。

5、微内核模式

对于一些专用的系统,主要是实时系统和“嵌入式”系统, “微内核”的思想就很有吸引力。究其原因,主要是因为通常这些系统都不带磁盘,整个系统都必须放在EPROM中,常常受到存储空间的限制,而所需要的服务又比较单一和简单。所以,几乎所有的嵌入式系统和实时系统都采用微内核,如PSOS,VxWorks等。
优点:

  • 良好的扩充性:只需添加支持新功能的服务进程即可
  • 可靠性好:调用关系明确,执行转移不易混乱
  • 便于网络服务,实现分布式处理:以同样的调用形式,在下层可通过核心中的网络传送到远方服务器上 (远地过程调用 RPC)。

缺点:将这些服务的提供都放在进程层次上,再通过进程间通信(通常是报文传递)提供服务,势必增加系统的运行开销,降低了效率,消息传递比直接调用效率要低一些 (但可以通过提高硬件性能来补偿 )。

6、NT执行体

运行在核心态内核的WindowsNT称为NT执行体。NT执行体结构是层次式与微内核的结合,它比UNIX内核小。基本上是一个完整的操作系统,它由一组部件构成,这些部件形成了层次结构。NT最底层是硬件抽象层(HAL),它将NT执行体的其余部分与运行机器硬件特性隔离开来。NT内核是第二层,它类拟于Mach的微内核,它负责对中断和异常作出响应;调度线程,提供一组基本对象和接口。

NT内核上是一组部件:对象管理程序、安全调用监视程序、进程管理程序、本地过程调用功能和虚拟内存管理程序等。I/O系统内部又分成若干层,它们是由I/O管理程序、文件系统、高速缓冲存储管理程序、设备驱动程序、网络重定向程序和网络服务器等组成。NT执行体最上层系统服务是NT执行体为用户态的进程提供的一个接口

7、保护子系统

WindowsNT 操作系统除NT执行体外,操作系统所有的其它部分被分成若干个相对独立的进程,每一个进程实现一组服务,称为服务器进程,它运行在用户态。用户态服务器进程又称保护子系统。WindowsNT有二类保护子系统:环境子系统和集成子系统。

环境子系统有Win32子系统、OS/2子系统和POSIX子系统几种,每种子系统为特定的操作系统提供一个API。它为客户进程提供服务是这样的:当一个应用程序调用其相应的某个API(本系统提供Win32、OS/2、POSIX、16位Windows和MS-DOS等系统的编程接口API)时,一个消息通过NT执行体的本地过程调用(LPC)工具,发送给完成该API程序的服务器进程-环境子系统。子系统执行API例程、并通过LPC将结果返回应用程序进程。

集成子系统是完成重要操作系统功能的服务器。这包括安全子系统,网络软件中的若干部件(工作站服务和网络服务器服务)。当用户试图进入系统时,首先必须进行登录,由安全子系统对用户进行是否允许其进入和权限检查与控制。安全子系统维护着一个有关帐号信息数据库,内容包括帐号名、保密字、用户权限等信息。任何非法用户或非法操作,都被安全系统拒之门外。

这里写图片描述

这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值