Windows 多进程模型 摘抄自《windows内核原理与实现》

3.1.1 多进程模型

现代操作系统总是提供可并发执行多个任务的环境,比如,用户可以一边接收电子邮件,一边听音乐,还可以同时跟网络上的朋友聊天。但是,现在主流的计算机只有有限的计算资源,例如只有一个单核处理器,较新的个人计算机可能配有一个双核或四核的处理器。让一个系统同时做几件不同的事情,这是现代操作系统的基本特征。假设计算机只有一个中央处理器,它该如何表现得可以同时处理这些任务呢?基本的做法是把时间细分,然后在某个适当的时间粒度上轮流执行这些任务,让每个任务都有机会被执行到。只要在人所能感知的时间粒度上(差不多是100~200 ms)每个任务都有机会做一点事情,用户就会认为这些任务是同时在执行。这种并行也被称为伪并行,而这样的系统被称为分时系统。有时候,计算机可能配有多个处理器,伪并行也有可能变成真并行,因为多个任务可以在多个处理器上真正地并行执行。Windows 操作系统能有效地支持这两种情形,它的任务调度算法可以很好地适应多处理器和多任务的情形。

我们可以简单地把进程(process)理解成一个独立的任务,它不仅是一个正在被执行的程序,有自己的指令流和内存空间,同时,还拥有一颗仅供自己使用的虚拟CPU。从整个系统的角度来看,多个进程是分时执行的,但是对于每个进程来说,它的指令流按顺序执行,就好像独占一颗CPU 一样。图3.1 显示了三个进程在同一个处理器上分时执行的效果。

 
(点击查看大图)图3.1 多个进程在一个处理器上分时运行

如图3.1 所示,每个进程都有自己的运行时间轴,感觉就像在一个单独的处理器上运行一样。系统负责切换这些进程,让它们得以轮流执行。当一个进程执行了一段时间以后,系统通过某种硬件机制或软件机制获得控制权,保留好这个进程的环境信息,包括内存空间、寄存器和指令流信息,然后挑选下一个要被执行的进程,恢复此进程的环境信息,并把控制权交给它,由它使用下一个时间片段。

因此,操作系统需要做的事情是:维护一个全局的进程表,记录下当前有哪些进程正在被执行;把时间分成适当的片段,在现代处理器结构中,这可以通过设置时钟中断来完成,因而每次时钟中断到来时系统就会获得控制权;在进程间实施切换,即保留上一个进程的环境信息,恢复下一个进程的执行环境。现在我们可以明白,每个进程在执行过程中实际上是经常被打断的,但由于系统能够准确地维护好进程的环境信息,所以,进程并不需要考虑自身的执行被频繁地打断这一事实,而是简单地认为自己是在持续地运行。一个聪明的进程通过读取系统的时间信息,可以估算出自己获得了多少真正有效的处理器运行时间。对于大多数进程而言,它们无须考虑这些因素。



3.1.2 进程与程序

理解了进程分时执行的情况以后,我们现在来看一看每个进程如何维护它自己独立的运行环境。在讲述进程环境以前,首先介绍一下程序的概念及其与进程之间的关系。在许多讲述C/C++程序设计的书籍或者材料中,都会提到一个程序的内存布局结构,如图3.2 所示。实际上,这里提到的程序内存结构与进程有一定的联系。每个程序必定是为了完成特定的功能或任务而存在,所以需要有代码来完成这些任务,但是仅仅有代码还不足以完成这些任务,还需要相应的存储单元来配合,包括内存和寄存器。

 
图3.2 一个C/C++程序的典型布局结构

在现代程序中用到的内存区域有三种类型:静态数据区、动态数据区,以及维护控制流信息和局部状态的调用栈区域。对于一个C/C++程序而言,静态数据区存放的是全局变量以及静态变量等信息,这是程序员在编写代码时就确定的数据区域;动态数据区则是在程序执行过程中根据需要而分配或回收内存的区域调用栈存放的是程序执行过程中的函数状态信息,当控制流从一个函数调用到另一个函数中时,调用栈记录了调用函数中的状态信息,包括所有的局部变量和当前指令流经过此次函数调用的位置。同时调用栈也用于传递函数参数。调用栈是实现函数调用的一种有效手段。

在一个程序的布局结构中,代码和静态数据区是可以预先确定的,命令行和环境信息也可以在启动一个程序的时候确定下来,但动态数据区和调用栈是程序运行过程中动态变化的。调用栈区域的大小通常是在程序启动时或者在程序的二进制属性中预先设置好,如果没有预设的值,则系统使用默认的大小。这些区域确定下来以后,中间的部分全部是动态数据区,由程序在运行过程中分配和管理。

现在我们回到进程的概念上来,如果一个程序是一个完全独立的模块,也就是说,它不依赖于任何其他应用模块就可以完成其既定的功能或任务,那么,图3.2 实际上也可以代表一个进程的内存布局。对于一个进程来说,它的存在之所以有意义,是因为它能完成特定的功能,这起码需要有一个对应的二进制模块,即前面所说的程序。然而,在实际的应用中,一个程序模块往往需要依赖于其他的模块来完成它的功能,比如某个第三方的二进制库。在这种情况下,图3.2 中的代码区和静态数据区在一个进程的内存布局结构中会有多份,每份对应于一个二进制模块。从这一层意义上讲,程序的概念相当于一个二进制可执行模块。由于这些被依赖的模块也可以称为程序,所以,程序的概念在不同的上下文环境中可能指代不同的事物。典型情况有两种:

  • 程序代表了一个进程,通常用启动该进程的二进制可执行模块的文件名来表示程序的名称。在Windows 平台上往往是一个.exe 文件。
  • 程序代表了一个二进制可执行模块,通常用该模块的文件名来表示程序的名称。在Windows 平台上,既可以是.exe 文件,也可以是DLL 文件或者其他后缀的文件。

当然,程序的概念还可以用于其他的情形,甚至指代源代码,这里不一一展开讨论。要记住的一点是,进程的概念是清晰和严格的,相对而言,程序的概念没那么清晰,两者之间既有区别也有联系,有时候甚至混用。所以,读者在阅读书籍或文章时,若看到程序一词,须注意上下文。

现在我们知道了,一个进程包含有代码和数据,以及在执行过程中有关控制流状态的信息,当它在运行过程中需要更多的内存时,它可以从动态内存区域获取内存,不用的时候再释放这些内存。为了建立起一个进程,需要一个初始的二进制可执行模块,来得到一个图3.2 所示的基本内存结构。如果该进程还需要额外的二进制模块,则这些模块的代码和静态数据区也会在适当的时候被引入到进程中来,并占据一定的内存空间。

操作系统只维护进程的基本信息,以便对系统中所有的进程实施管理,包括为每个进程分配处理器时间,以及在进程之间进行切换。既然进程是操作系统完成各种任务的基本载体,那么操作系统如何控制进程的创建和终止呢?

首先,操作系统在引导过程中,必须把系统运行所必要的进程全部创建起来。所谓创建一个进程是指建立起基本的进程执行环境,然后把它加入到系统的全局进程表中,使它有机会得到处理器时间和其他系统资源,以后,这个进程就可以按照其自身的逻辑独立运行了。所以,操作系统会创建一组初始的进程,这是在系统引导时完成的。

其次,在一个系统的运行过程中,一个进程在必要的时候可能会创建其他的进程。虽然普通进程无法完成创建一个进程所需要的各种步骤,但是它可以请求系统帮它创建一个进程。这实际上建立起了进程之间的父子关系或从属关系,即父进程创建子进程。另外,一个进程也可以为了响应用户的请求而创建一个新的进程。比如用户通过某种方式要求编辑一个文本文件,系统中当前正在运行的进程接收到用户的请求以后,创建一个新的子进程来打开并编辑指定的文本文件。除了系统的初始进程以外,其他的进程都是在系统运行过程中根据需要而创建的

进程如何终止呢?当一个进程完成了所有预定的功能以后,它的使命便已结束,最后的职责是通知操作系统,自己要终止了。操作系统接到请求以后,清理掉这个进程所占据的各种资源,使它们能被回收,并且将该进程从系统的全局进程表中移除,所以以后不会再给它分配任何处理器时间。这是比较温和、友好的进程终止做法。在其他有些情况下,即使一个进程还没有完成其任务,它也可能被另外的进程或者系统终止。比如,当进程出错或者状态不正确时,系统一旦检测到其错误并且认为这是不可恢复的,则会强制终止此进程。另外,由于进程之间可能存在逻辑上的关联关系,所以,一个进程可能会要求系统终止另一个进程,即俗称的“杀死一个进程(kill a process)”。

前面提到了,一个进程可能会包含多个二进制可执行模块,它们的代码区和静态数据区都被引入到进程的内存空间中,但是,动态数据区可能是系统全局的,也可能每个模块有其特有的动态数据区,这取决于每个模块自己的实现,但从概念上讲,它们的动态数据区应该是进程全局共享的。另外一个没有提及的重要方面是,默认情况下进程只有一个控制流,尽管这个控制流可以跨越多个模块,但是它的调用栈只有一个。在现代操作系统结构中,进程可以有多个控制流,每个控制流对应一个调用栈。操作系统在创建进程时仅建立一个控制流,但是在该控制流的执行过程中,它又可以创建额外的控制流,这样便形成了一个进程多个控制流的情形。这里的控制流实际上正是下一节要讨论的线程概念。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值