欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    UNIX的进程管理.ppt

    • 资源ID:6522538       资源大小:464.50KB        全文页数:187页
    • 资源格式: PPT        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    UNIX的进程管理.ppt

    第二章 UNIX的进程管理,李陶深,2.1 UNIX进程管理的几个要点,(1)进程在一个地址空间上执行单一指令序列。进程地址空间包括可以访问或引用的内存单元的集合,进程控制点通过一个一般称为程序计数器(PC)的硬件寄存器控制和跟踪进程指令序列。许多较新的UNIX版本支持多个控制点(称为线程),因此在一个进程内可以有多个指令序列。,2.1 UNIX进程管理的几个要点,(2)UNIX系统是一个多道程序环境,即几个进程可以同时在系统中并发活动。系统为这些进程提供虚拟机的某些功能。在一个纯虚拟机结构中,操作系统给每个进程一个它是系统唯一进程的假象。程序员在写应用程序时,可以认为系统中只有他的代码在运行。在UNIX系统中,每个进程有自己的寄存器和内存,但必须通过操作系统才能进行I/O和设备控制。,2.1 UNIX进程管理的几个要点,(3)进程地址空间是虚拟的,通常只有部分映射到物理内存单元上。内核将进程地址空间的内容保存在备种存储对象上,包括物理内存,磁盘上的文件,特别地还可以保存在本地和远程磁盘的交换区上。通常由内核的内存管理子系统完成进程存储页面在这些对象之间的转移。,2.1 UNIX进程管理的几个要点,(4)每个进程还有一组对应于实际硬件寄存器的寄存器。系统中有许多活动进程,但只有一组硬件寄存器。内核将当前运行进程的寄存器组保存在硬件寄存器中,将其他进程的寄存器组保存在每个进程的数据结构中。,2.1 UNIX进程管理的几个要点,(5)进程间会竞争系统中的各种资源,例如处理器,内存和外围设备。对于CPU这样的资源,内核限制每个进程在CPU上运行一个小段时间(称为定额,一般为10毫秒左右),然后再切换到另一个进程。通过这种方法,内核给每个进程一种并发运行的假象。这样,每个进程获得一段CPU时间并继续执行。这种操作方法称为时间片。,2.1 UNIX进程管理的几个要点,(6)应用程序员并不关心设备的功能和结构的底层细节。操作系统拥有对这些设备的完全控制,并提供一个高级抽象编程接口,应用程序可以通过这些接口访问这些部件。这样就隐藏了硬件的所有细节,大大简化了程序员的工作。通过对这些设备的集中控制,还可以提供一些诸如访问同步(若两个用户在同一时刻想访问同一设备)和错误恢复等其他功能。应用编程接口(API)定义了用户程序和操作系统之间的所有交互语义。,核心,系统调用接口,设备访问接口,用 户 进 程,系统进程,终端,打印机,各种外部设备,存储设备,图2.1 内核号进程及设备间的交互,2.1 UNIX进程管理的几个要点,内核是一个直接运行在硬件上的特殊程序,它实现了进程模型和其他系统服务。它在磁盘的文件一般是/vmunix或/unix(这取决于UNIX厂商)。当系统启动时,通过一个称为引导程序(bootstrapping)的特殊过程从磁盘上加载内核。内核初始化系统,为运行进程设立环境。然后它创建一系列初始进程,这些进程接着又创建其他进程。一旦被加载后,内核将一直保留在内存中,直到系统关闭为止,它管理所有进程并为它们提供各种服务。,UNIX操作系统借助以下4种方式提供功能:用户进程通过UNIXAPI的内核部分,系统调用接口,显式地从内核获得服务。内核以调用进程的身份执行这些请求。进程的某些不正常操作,诸如除数为0,或用户堆栈溢出将引起硬件异常。异常需要内核干预,内核为进程处理这些异常。内核处理外围设备的中断。设备通过中断机制通知内核I/O完成和状态变化。内核将中断视为全局事件,与任何特定进程都不相关。像Swapper和pagedaemon之类的一组特殊的系统进程执行系统级的任务。比如,控制活动进程的数目或维护空闲内存池。,2.2 进程的描述要点,为了实施对进程的有效管理,操作系统为每个进程设置了一个进程控制块(PCB)。在UNIX 版本六中,将PCB分成Proc结构、User结构、text结构。在UNIX System V中,将PCB分成进程表项和U区。除进程表项和U区外,管理进程的据结构还有本进程区表和系统区表。1进程表项 进程表项中的每个表目主要包含以下信息:,UNIX版本的PROC结构struct proc char p_stat;/*进程的运行状态*/char p_flag;/*进程的标志域*/char p_pri;/*进程的优先数*/char p_sig;/*进程接收到的中断号*/char p_uid;/*进程拥有者的用户ID*/char p_time;/*进程在内存中的驻留时间*/char p_cpu:/*进程的使用cpu时间*/char p_nice;/*计算进程优先数的偏置量*/int p_ttyp;/*控制终端*/int p_pid;/*当前进程的进程ID*/int p_ppid;/*当前进程父进程的进程ID*/int p_addr;/*交换区的地址*/int p_size;/*进程文件的大小*/int p_wchan;/*进入睡眠的原因*/int*p_textp;/*指向文本区的指针*/procNPROC;,UNIX System V的进程表项(1)标识进程状态的状态域。UNIX System V中共有9个状态。(2)若干用户标识号,简称UID或用户ID。这些用户标识号指出该进程属于哪一用户,具有何种特权,如是否可以互相发送救中断信号等。(3)若干进程标识号,简称PID或进程ID,说明进程间的相互关系。(4)存储区位置和长度,指明进程在内存或外存中的位置及大小。这些信息在进程换入换出及状态转换时用到。,(5)调度参数,包括优先数等。核心利用它们决定进程转换到核心态和用户态的次序,以及占有处理机的次序。(6)软中断信号域,记录发向一个进程的所有未处理的软中断信号。(7)各种计时域,给出进程执行时间和系统资源的利用情况。这些信息用来为进程记账、计算调度优先数以及发送闹钟信号等。(8)指向U区的指针。(9)事件描述域,记录使进程进入睡眠状态的事件。,2UNIX System V 的U区 U区中的各个域进一步刻画了进程的特性,U区主要包含以下信息:(1)指向进程表项的指针,指出对应于该U区的进程表项。(2)真正用户标识符(real user ID)及有效用户标识符(effec-tive user ID),决定进程的各种特权,如文件存取权限等。(3)用户文件描述符表,记录该进程已打开的文件。(4)当前目录和当前根,描述进程的文件系统环境。,(5)计时器域,记录进程及其后代在核心态和用户态运行所用的时间。(6)一些输人脑出参数,描述要传输的数据量,在用户空间的源(或目的)数据的地址,文件的输入输出偏移量等。(7)限制域,指出进程的大小及它能“写”的文件大小限制。(8)出错域,记录系统调用执行期间所发生的错误。(9)返回值域,它指出系统调用的返回结果。(10)信号处理数组,指出进程接收到软中断信号时的处理方式。,UNIX版本的User结构 Struct user int u_rsav2;/*当进程不执行时保存r5,r6,不代表不在运行状态*/char u_segflg;/*进程所处的运行状态,0表示用户态,1表示核心态*/char u_error;/*运行错误编号*/int u_procp;/*进程指针,指向U区对应的进程表项*/int*u_cdir;/*当前目录i节点地址*/int*u_pdir;/*父目录i节点地址*/int u_uisa16;/*段寄存器中的页地址寄存器*/int u_uisd16;/*段寄存器中的页说明寄存器*/int u_arg5;/*系统调用时传递的参数*/int u_tsize;/*正文区的大小*/int u_dsize;/*数据区的大小*/int u_ssize;/*栈区的大小*/int u_sep;/*正文区分开存储的标志*/int u_qsav2;/*当进程被中断时保存r5,r6*/int u_ssav2;/*当进程被换出是保存r5,r6*/int*u_ar0;/*寄存器R0的地址*/,3系统区表 UNIX System V把一个进程的虚地址空间划分为若干连续的逻辑区,有正文区、数据区、栈区等。这些区是可被共享和保护的独立实体,多个进程可以共享一个区。为了对区进行管理,在核心中设置了一个系统区表(简称区表),各表项中记录了描述活动区的有关信息:(1)区的类型和大小。(2)区的状态。一个区具有这样几种状态:锁住、在请求中、在装入过程中、有效(区已装人内存)。(3)区在物理存储器中的位置。(4)引用计数。共享该区的进程数。(5)指向文件索引节点的指针。,4本进程区表 为了记录进程的每个区在进程中的虚地址,并通过它找到该区在物理存储器中的实地址,系统为每个进程配置了一张进程区表,表中每一项记录一个区的起始虚地址及指向系统区表中对应区表项的指针。这样,核心通过查找本进程区表和系统区表,便可将区的逻辑地址变换为物理地址。这里使用两张表来对区地址进行映像是为了便于实现区的共享。,2.3 进程的状态及其转换,在 UNIX System V中,为进程设置了 9种状态。(1)创建状态:进程刚被创建时,进程已经存在,但尚未完全获得运行所必须具有的资源,因此它既不是就绪状态,也不是睡眠状态。这个状态可被认为是进程的初始状态。(2)内存中就绪:进程已在内存中且处于就绪状态。对于新创建的进程,若系统有足够的内存,核心便将它装入内存,从而使新进程转入内存中就绪状态。(3)就绪且换出:进程处于就绪状态,但被换出到外存中。在创建新进程时,若无足够的内存,核心便将新进程安置在外存对换区中,并赋予就绪且换出状态。此外,原已在内存中的进程,可能因内存紧张而被换出,同样也成为就绪且换出状态。,(4)核心态执行:进程在核心态下执行。(5)用户态执行:进程在用户态下执行。(6)内存中睡眠:进程已在内存中且正处于睡眠状态。例如,进程所执行的系统调用涉及到I/O操作,而进程又须等待I/O操作的完成,则进程将进人内存中睡眠。(7)睡眠且换出:当内存紧张时,在内存中睡眠的进程,首先被核心换出到外存上,以腾出内存。此时,进程将变为睡眠且换出状态。(8)被剥夺状态:当进程从核心态返回用户态时,核心剥夺了该进程的处理机,使该进程处于被剥夺状态。(9)僵死状态:进程执行了exit系统调用后,便处于僵死状态。此时,进程已不存在,但它留下一些含有状态码和一些计时统计信息的记录,供父进程收集。,用户态运行 系统调用 中断 返回 返回用户态 僵死 核心态运行 退出 抢先 睡眠 重新调 度进程 被抢先在内存 中睡眠 唤醒 在内存中就绪 换 出 fork 换出 换入 创建睡眠 内存不足 且换出 就绪且换出 图22 UNIX系统的状态转换图,9,4,6,5,2,7,1,3,8,2.3 进程的状态及其转换,由图22可以看出,UNIX把执行状态分为两种:一种是用户态执行;另一种是核心态执行。处于用户态执行时,进程所能访问的内存空间和对象受到限制;而处于核心态执行时,进程能访问所有的内存空间和对象。进程在核心态执行时,是不允许被剥夺的;而运行在用户态时是可以被剥夺的。此外,还有两个状态是等效的,一个是内存中的就绪状态,处于这种状态的进程可以被调度而执行;另一个是被剥夺状态,当运行进程要从核心态执行返回到用户态执行时,核心可剥夺该进程的运行而调度另一进程执行,这时被剥夺的进程便转换为被剥夺状态。因而,处于这两种状态的进程是等效的,它们被排列在同一队列中等待再次调度。,2.4 进程上下文,当一个进程在执行时,可看作是在它的进程上下文中执行。每个进程都有一个严格定义的上下文,包括描述这个进程的所有信息。上下文由几个部分组成:用户地址空间。一般划分为几个部分程序正文(可执行代码),数据,用户堆栈,共享内存区,等等。控制信息。内核使用两个数据结构维护进程的控制信息u区和proc区结构。每个进程也有它自己的内核堆栈和地址转换表。凭证。进程的凭证包括与其相关的用户ID和组ID。,2.4 进程上下文,环境变量。这是一些形如:variablevalue的字符串组,是从其父进程继承过来的。大多数UNIX将其存在用户栈底。标准输入输出库提供对这些变量的增加,删除,更改以及将从变量中取值的函数。当调用一个新程序时,调用者用exec取得原始环境或提供一组新的变量。硬件上下文。这包括通用寄存器中的值以及一组特殊的系统寄存器。系统寄存器包括:程序计数器(PC),它记录将要执行的下一指令地址。堆栈指针(SP),它包括栈顶元素的地址。,2.4 进程上下文,处理器状态字(PSW),它包括几个表明系统状态信息的状态位,如当前和以前的执行模式,当前和以前的中断优先级溢出以及进位位。内存管理寄存器,它对应进程的地址转换表。浮点单元(FPU)寄存器。程序寄存器包括当前正在运行进程的硬件上下文。当发生上下文切换时,寄存器中的值都保存到当前进程u区(称为进程控制块,PCB)的特定部分。内核选择一个新进程运行时,将从PCB中装载硬件上下文。,2.4 进程上下文,一个进程的上下文(context)由三部分组成:用户级上下文、寄存器上下文和系统级上下文。1用户级上下文 用户级上下文是由进程虚地址空间中的正文、数据、用户栈和共享存储区组成。在采用对换和请求调页存储管理方式时,只有进程的部分虚地址空间驻留在内存。但无论它是否驻留在内存,都属于用户级上下文的组成部分。,2.3 进程上下文,2寄存器上下文 寄存器上下文主要由CPU中的一些寄存器内容构成。主要的寄存器有:程序计数器(PC),它记录将要执行的下一指令地址。堆栈指针(SP),它包括栈顶元素的地址。处理器状态字(PSW),它包括几个表明系统状态信息的状态位,如当前和以前的 执行模式,当前和以前的中断优先级溢出以及进位位。内存管理寄存器,它对应进程的地址转换表。浮点单元(FPU)寄存器。,2.3 进程上下文,3系统级上下文 系统级上下文可分为静态和动态两部分:(1)静态部分 在进程的整个生命期中,系统级上下文的静态部分只有一个,其大小保持不变,它由三部分组成:进程表项:每个进程有一个表项,其中记录了进程的状态及有关控制信息。U区:U区中的各个域进一步刻画了进程的特性。本进程区表项、系统区表项和页表:用于实现进程的逻辑地址到物理地址的映射,2.3 进程上下文,(2)动态部分 在进程的整个生命期中,系统级上下文动态部分的数目是可变的。它包括:核心栈:进程在核心态执行时使用的栈。若干层寄存器上下文:其中每一层都保存了前一层的寄存器上下文。下图显示了进程上下文的组成。图的左边是上下文的静态部分,它由用户级上下文和系统级上下文的静态部分所组成。图的右边是上下文的动态部分,它由几个栈结构组成,其中每个栈结构中包含保存的前一层寄存器上下文和当核心在该层执行时的核心栈。核心的上下文层0是虚设层,它表示用户级上下文。,图2.3 进程上下文的组成,上下文静态部分 上下文动态部分,用户级上下文 进程正文 数 据栈 共享数据系统级上下文静态部分 进程表项U 区 本进程区表,核心栈第层第二层的保存的、寄存器上下文核心栈第2层第一层的保存的、寄存器上下文核心栈第1层第0层的保存的、寄存器上下文,核心上下文 0层,应用程序 系统调用(用户)指令 异常(只访问进程空间)(可以访问进程及系统空间)(只访问系统空间)不 允 许 中断、系统任务,进程上下文,系统上下文,用户态,核心态,图2.4 执行模式及上下文,有三种事件会导致系统进入内核态设备中断,异常,自陷或软中断。在每一种情况下,当内核接收到控制权,它依赖于派遣表控制转移方向。派遣表中包括处理这些事件的底层例程的地址。在调用相应的例程前,内核在内核栈上保存被中断进程的某种状态(如它的程序计数器,处理器状态字)。当例程完成后,内核恢复进程的状态,并将执行模式恢复为原来的模式(在内核态发生中断时,中断处理程序完成后仍返回内核态)。,这里有必要区分中断和异常。中断是由外围设备,如磁盘,终端或硬时钟引起的异步事件。由于中断不是当前正在运行的进程引起的,它们必须在系统上下文中被处理,而不可以访问进程地址空间和U区。同理,它们也不能被阻塞,否则会阻塞其他进程。异常对进程而言是同步的,是由进程自身相关的事件引发的,如除0或访问非法地址。因此异常处理程序应在进程上下文中运行,它可访问进程的地址空间和u区,必要时可以被阻塞。软件中断或自陷,在系统执行特殊指令时出现,如有系统调用,在进程上下文中同步处理。,2.5 进程控制与调度,在 UNIX中,进程既是一个独立拥有资源的基本单位,又是一个独立调度的基本单位。为了对进程进行控制,UNIX提供了一系列系统功能调用,用户可以利用它们来实现“创建一个进程”或“终止一个进程的执行”等功能。,2.5.1 进程控制,在UNIX系统中,用于对进程实施控制的主要系统调用有:fork,用于创建一个新进程;exec,执行一个文件;exit,使进程自我终止;wait,等待子进程终止。1系统调用fork 在UNIX系统中,除了0进程外,其他所有进程都是被另一个进程利用fork创建的。0进程是一个特殊的系统进程,它是在系统引导时被创建的。系统初启时,0进程又创建1进程,此后0进程就变为对换进程,而1进程就变为系统的始祖进程。UNIX利用fork为每个终端创建一个子进程为用户服务,如等待用户登录、执行shell命令解释程序等。此后,每个终端子进程又可利用fork来创建它的子进程,从而可形成一棵进程树。,1系统调用fork,fork系统调用的语法格式如下:int fork();fork系统调用没有参数,如果执行成功,则创建一个子进程,子进程继承父进程的许多特性,并具有与父进程完全相同的用户级上下文。核心为fork完成下列操作:(1)为新进程分配一进程表项和进程标识符。进入fork后,核心检查系统是否有足够的资源来建立一个新进程。若资源不足,则fork系统调用失败;否则,核心为新进程分配一进程表项,并赋予一个惟一的进程标识符。,1系统调用fork,(2)检查同时运行的进程数目。对于一个普通用户,其所能建立的进程数是有限的,且当进程表中仅剩下最后一个进程表项时,不能由普通用户占用。因此对普通用户而言,超出此限制值或进程表中仅剩下最后一个进程表项时,fork系统调用失败。(3)复制进程表项中的数据。核心初始化子进程的进程表项,把它置为创建状态,然后把父进程表项中的数据复制到子进程的进程表项中。,系统调用fork,(4)子进程继承父进程的所有文件。核心首先对父进程的当前目录的引用计数加1,其次若有改变的根目录,也对其引用计数加1:再找出父进程已经打开的所有文件,并将相应的文件表项中的引用计数都进行加1操作。这样,子进程便继承了父进程的所有文件,从而可与父进程共享这些文件。(5)为子进程创建进程上下文。核心先为子进程创建进程上下文的静态部分,并将父进程上下文的静态部分复制到子进程的上下文中。然后,再为子进程创建进程上下文的动态部分。至此,进程的创建即告结束。,系统调用fork,(6)进程执行。若正在执行的进程是父进程,则将于进程的状态设为内存中就绪,并将于进程的进程标识符返回给用户,从而完成了它的那部分fork调用;若正在执行的进程是子进程,则它将执行子进程的那部分fork调用,初始化U区的计时字段后,将0作为系统调用的返回值。由于父进程和子进程都是从fork返回并继续执行同一程序,需要一种方式区分它们,并使它们能照此运行。否则,不同进程将不可能做不同事。出于这种考虑,fork系统调用为父子进程返回不同的值子进程中fork返回0,父进程中返回子进程的PID。,为了便于理解UNIX系统进程的并发性,将进一步探讨fork 的实现过程。请看下面UNIX版本6的fork()源码:fork()register struct proc*p1,*p2;p1=u.u_procp;/*指针p1指向当前进程(父进程)的proc项*/*在proc数组中搜索以找到一个空的proc结构,若p_stat的值为null,则该proc项为空*/for(p2=/*对于子进程,返回父进程标识的值*/,/*以下为各个计时参数赋初值*/u.u_cstime0=0;/*所有子进程在核心态所用时间之和*/u.u_cstime1=0;u.u_stime=0;/*该进程的在核心态下执行所用时间*/u.u_cutime0=0;/*所有子进程在用户态所用时间之和*/u.u_cutime1=0;u.u_utime=0;/*该进程的在用户态下执行所用时间*/return;u.u_ar0R0=p2-p_pid;/*对于父进程,返回子进程标识的值*/out:u.u_ar0R7=+2;/*使用户态程序计数器(PC)值加2(一个字)*/,从上面源码看到,fork首先在 proc数组中搜寻一空闲项,若找到空闲项,用p2记住该项的位置。接着Fork会设置新进程的PID和状态、使子进程与父进程共享正文段和打开文件、为子进程申请数据段内存空间等。这些工作正是由newproc过程完成的(见代码中的(5)语句)。可以说,fork的大部分工作都由newproc来完成。进入newproc过程时,找到一区别于其他所有进程的标识号来作为子进程的标识号。newproc也独自搜寻proc的空项,但他找到的空项与之前fork找到的是同一项。之后,newproc将父进程进程表项中的数据拷贝到子进程表项中,置子进程状态为就绪态,设置进程标识号。为了使子进程与父进程共享正文段,把父进程指向正文段的指针赋予子进程,使他们指向同一正文段,同时将正文段控制块中进程的引用数加1。,newproc()为新进程分配一个未用的进程ID和一个进程表项;为进程表项的部分分量赋初值;父进程引用的所有文件引用计数加1;if(父进程文本区不为空)文本的引用计数加1;当前目录的i节点引用计数加1;保存r5,r6(环境指针,栈指针)到u.u_rsav中;u.u_proc=新申请子进程进程表项地址;a1=当前进程-p_addr;a2=为子进程分配的和当前进程同样大小的内存空间;,if(a2=0)当前进程-p_stat=SIDL;子进程-p_addr=a1;保存r5,r6到u.u_ssav中;将子进程换出;当前进程-p_stad=SRUN;else 子进程-p_addr=a2;复制当前进程的U区数据给子进程;u.u_proc=父进程进程表项地址;,/*-sampfork.c.-*/#include“stdio.h”#includemain(int argc,char*argv)int pid,ret_code,ret_val;if(argc 1)signal(SIGCLD,SIG_IGN);/*.(1),忽略子进程死*/pid=fork();/*创建新进程*/if(pid 0)/*若创建失败*/fprintf(stderr,”fork failed!”);/*打印出错信息*/exit(1);if(pid=0)/*在子进程中*/execl(“/usr/child”,”child”,0);/*(2)*/sprintf(stderr,”execlerr”);exit(0 x5);/*.(3)*/,else/*pid 0,在父进程中*/ret_val=wait(这个程序表面看是串行程序,但由于有了fork调用,实际是一个并发程序。返回值小于0,表示创建子进程失败,则提示出错后回到上一级进程或操作系统提示符(shell)。若fork()产生一子进程成功,则该程序在机器中产生一逻辑副本,父进程就是利用这一特性在创建子进程时将有关数据传给子进程的。当调度到父进程(即fork返回值为子进程标识号且大于0)时,执行父进程程序段;当调度到子进程(pid为0)时,执行子进程程序段;父、子进程的程序段都会得到执行,只是执行时间和顺序上有所差别。,2系统调用exec,fork系统调用只是将父进程的上下文复制到新进程中,因此执行完fork时,父子进程具有完全相同的正文区、数据区及用户栈区。若要使新进程执行的程序不同于父进程,可以使用exec系列系统功能调用。exec调用不创建新进程,而是引用另一个程序,它用一个可执行文件的副本覆盖调用进程的存储空间,从而改变调用进程的正文段、数据段,并以调用进程提供的参数转去执行这个新的正文段程序。与fork不同,exec调用成功后将不返回到调用进程(因为调用进程已经被覆盖),而是回到它所取代的进程的上一级进程或操作系统提示符(shell),只有exec失败时才返回到调用进程。,2系统调用exec,exec调用有几种格式,它们的区别主要在参数处理方法上,参数涉及被加载程序名参数、环境变量和路径变量。exec调用给出参数的形式有两种,一种是直接给出指向每个参数的指针,另一种是给出指向参数表的指针。下面只给出两种基本的exec调用格式的说明,例如:int execl(path,arg0,arg1,argn,0);chart*path,*arg0,*arg1,*argn:int execv(path,argv);char path,argv;,系统调用exec,exec系列中的系统调用都完成同样的功能,它们把一个新的程序装入调用进程的内存空间,以改变调用进程的执行代码,从而使调用进程执行新引入的程序功能。如果exec调用成功,调用进程将被覆盖,然后从新引入程序的入口开始执行。这就产生了一个新进程,它的进程标识符与调用进程相同,但所执行的程序代码不同。这就是说,exec没有建立一个与调用进程并发执行的新进程,而是用新进程取代了老进程。,系统调用exec,exec系统调用必须执行下述任务;1)分析路径名并访问可执行文件。2)验证调用者有执行该文件的权限。3)读文件头并检查它是合法可执行的。4)若文件的模式中有SUID或SGID位标识,把调用者的有效UID或GID分别改变为这个文件的属主的UID和GID。5)将exec的参数和环境变量复制到内核空间,当前用户空间将当被删除。6)为数据和堆栈区分配交换空间。7)释放旧的地址空间及相关的交换空间。若进程由fork创建,将老空间返回父进程。,2系统调用exec,8)为新的正文,数据和堆栈分配地址转换表。9)设置新的地址空间。若正文区已经处于活动状态(某些进程巳在运行同一程序),那么就共享它。否则,从可执行文件中读取它。UNIX进程一般是分页式,即只有当程序需耍时,才将页面读入内存。10)将参数和环境变量复制到新的用户栈上。11)由于原处理函数不在新程序中,将所有信号处理函数重置为缺省动作。在调用exec前被忽略或阻塞的信号仍忽略或阻塞。12)初始化硬件上下文。大多数寄存器设为0,计数器设置为程序入口点。,许多情况下,子进程从fork返回后很快会调用exec来开始执行新程序。(库函数提供几种不同形式的exec,如exece,execve和execvp。每个使用一组稍有不同的参数,预处理后调用同一系统调用。这个一般名称exec可指代这组函数中的任一函数。下面例子中就是fork和exec的常用组合。if(result=fork()=0)/*child code*/.if(execve(/usr/child,child,0)0)perror(execve failed);exit(1);else if(result 0)perror(fork);/*fork failed*/*parent contonue here*/.,由于exec用新程序覆盖已有的进程,子进程不会返回旧程序,除非exec失败。exec调用成功后,子进程的地址空间替换为新程序的地址空间,子进程返回后程序计数器中将是新程序的第一条可执行指令。把fork和exec分开有很多好处。在许多客户服务器应用中,服务器程序可能会fork许多执行同一程序的进程。相反,有时程序只需执行新程序而无需创建新进程。最后,在fork和exec之间,子进程可以有选择地执行一系列任务以确保新程序以所希望的状态运行。这些任务包括:重定向标准输入,输出或错误。关闭从父进程继承来的而新程序并不需要的打开文件。改变UID或进程组。重置信号处理程序。若单一系统调用试图完成所有这些功能将是笨重而低效的。现有的fork-exec框架提供了更强的灵活性,清晰而且模块化强。,3系统调用exit,对于一般的用户进程,在其任务完成后应尽快撤消。为了及时回收进程所占用的资源并减少父进程的干预,UNIX系统利用exit来实现进程的自我终止。通常,父进程在创建子进程时,应在子进程的末尾安排一条exit,使子进程自我终止。exit的语法格式如下:void exit(status);int status;其中,status是返回给父进程的一个整数,以备父进程检查。如果调用进程在执行exit时,其父进程正在等待它的终止,则父进程可立即得到它返回的整数。,exit()当前进程跟踪标志复位;将U区的信号状态全部设置为1;/*此值为奇数时忽略对应的软件中断*/将与当前进程打开的文件引用数减1,为0时副作用是关闭此文件,并将U区的文件引用清空;将当前目录的引用数减1,为0时的副作用是释放该i节点;处理当前进程引用的正文段;a=在磁盘交换区中申请一块存储空间;将U区(共289字节)的前256个字节拷贝到a中;释放当前进程所占用的内存;当前进程-stat=SZOMB;,loop:for(p=,注1:loop开始的循环结构包含一个由if引导的内循环,而变量均为p,这样当内循环变量改变时,也会影响到外循环。又因为两个循环的结束条件相同,所以内循环结束时,外循环也随之结束。然后在改变当前进程父进程后,又开始新的循环,以后保持父进程为进程1不变,而当前进程也没有了子进程。注2:本过程进入死循环,处于SZOMB状态不变,直到进程1调用wait时才使其结束。,4 系统调用wait,系统调用wat用于将调用进程挂起,直至其子进程因暂停或终止而发来软中断信号为止。如果在wait调用前,已有子进程暂停或终止,则调用进程作适当处理后便返回。wait调用的语法格式如下:int wait(stat_loc);int stat_loc;其中,stat_loc是用户空间的一个地址,它含有子进程的退出状态码。,wait()f=0;/*f表示调用此过程的过程的子进程数。*/loop:for(p=,if(p-p_stat=SSTOP)if(未设置进程p的SWTED标志)设置进程p的SWTED标志;把进程p的进程ID保存到寄存器R0中;把p-p_sig的低8为保存到寄存器R1中;return;清除进程p的STRC和SWTED标志;setrun(p);if(f)sleep(u.u_procp,PWAIT);goto loop;置错误标识为ECHILD;,wait系统调用可以使进程等待子进程终止。由于子进程的终止可能早于wait调用,wait也必须处理这种情况。wait首先检查调用者是否有死亡或挂起的子进程。若有立即返回,若没有死亡的子进程,wait阻塞调用者,等待它的一个子进程终止,并立即返回。在上述两种情况下,wait返回死亡子进程的PID,将子进程的退出状态写入stat_loc,并释放它的proc结构(若多于一个进程死亡,wait只对其找到的第一个做处理)。若子进程正被跟踪,在子进程收到信号时wait也返回。若调用者没有子进程(死的或是活的),或wait被信号中断,wait返回错误信息。,5.僵尸(Zomble)进程,进程退出后,在父进程清除它以前,它一直处于僵尸状态。在这个状态下,它所保留的唯一资源就是proc结构,其中包括退出状态和资源使用信息。这些信息可能对父进程有用。父进程通过调用wait获取这个信息,wait也释放proc结构。若父进程先于子连程死亡,init将继承它的子进程。当这些子进程死亡时,init调用wait释放子进程的proc结构。,5.僵尸(Zomble)进程,当一个进程先于父进程死亡而父进程又没有调用wait时会产生一个问题。子进程的proc结构将不会释放,子进程会一直保持僵尸状态直到系统重启。这种情况很少发生,因为shell尽一切可能避免这种情况。然而,它会发生于一个粗心大意写成的应用程序,它没有等待它的子进程。这种情况非常令人讨厌,因为这种僵尸将可以在ps输出中看见(同时用户很着急的发现它们不能被杀死他们己经死亡)。更重要的是,它们占用proc结构,因而会减少处于活动状态的迸程总数。,6.Stop调用,stop()loop:cp=当前进程;if(cp的父进程!=#1进程)for(pp=,2.5.2 进程调度,1 传统UNIX的调度策略 CPU是一个由所有进程共享的资源。内核中在进程间分配CPU时间的那部分称为调度器(scheduler)。传统UNIX调度器使用抢占式轮转调度。相同优先级的进程以轮转方式调度,每个运行一个固定的时间片(通常是100毫秒)。若有一个更高优先级的进程准备就绪,无论当前进程是否用完其时间片,它都会被那个高优先级进程抢占(除非当前进程正在内核态运行)。,1 传统UNIX的调度策略,传统UNIX系统中,进程优先级由两个因素决定的nice值和usage因子。用户通过nice系统调用更改进程的nice值,影响进程的优先级(只有超级用户可以增加进程优先级)。usage因子是对进程近期使用CPU的度量。它允许内核动态的改变进程优先级。当进程不在运行时,内核定期增加它的优先级。当进程正在占用CPU时间时,内核减少其优先级。由于就绪进程的优先级最终会升到足够高而被调度,这种策略会防止某些进程的饿死现象。,1 传统UNIX的调度策略,在内核中运行的进程由于阻塞于资源或事件而放弃CPU。当它再次变为就绪后,它被赋予内核优先级。内核优先级高于任何用户优先级。传统UNIX内核中,调度优先级的值范围是0127的整数,值越小,优先级越高-。(由于UNIX系统绝大部分用C写成,它遵循标准习惯从0开始计数)。例如,4.3BSD中内核优先级为049,用户优先级50127。用户优先级随CPU使用的不同而变化,而内核优先级是固定的,因睡眠原因而定。正因为如此,内核优先级也称为睡眠优先级。,2 UNIX System V的调度策略,该系统对进程的调度采用多级反馈队列轮转调度方式。相应地,在系统中便为就绪进程设置了多个就绪队列。调度程序在进行调度时,总是先从最高优先级队列中取出排在队列最前面的进程。仅当最高优先级队列中没有进程时,才从次高优先级队列中找出其队首进程,令它执行一个时间片后,又剥夺该进程的执行,然后,再从优先级最高的队列中取出下一个就绪进程投入运行。,2 UNIX System V的调度策略,(1)进程优先级的分类 在UNIX系统中,进程的优先级分为两类:1)核心优先级:它又可进一步分为可中断和不可中断两类优先级。当一个软中断信号到达时,若进程正处于可中断优先级上睡眠,则进程立即被唤醒;若进程处于不可中断的优先级上,则进程继续睡眠。例如,“对换”、“等待磁盘I/O”、“等待缓冲区”和“等待索引节点”这几个优先级均属于不可中断优先级;而“等待TTY输入”、“等待TTY输出”和“等待子进程退出”这几个优先级是可中断优先级。2)用户优先级又可分成nl级,其中第0级为最高优先级,第n级的优先级最低。,2 UNIX System V的调度策略,(2)优先级的计算 UNIX System V中的用户优先级是可变的,它随着占用 CPU时间的增加而降低。核心每隔1秒钟便根据一个衰减函数来调整每个进程的最近CPU使用时间,并按下述公式对各进程重新计算其用户优先数(优先数越大,优先级越低;优先数越小,优先级越高)。decay(CPU)CPU2 优先数最近使用 CPU的时间2+基本用户优先数 UNIX所用的进程调度算法首先从处于“内存就绪”或“被剥夺”状态的进程中选择一个优先级最高的进程。若系统中同时有多个进程都具有最高优先级,则核心将选择其中处于就绪状态最久的进程,将它从所在队列中移出,恢复其上下文,使之执行。,3 进程的切换,在操作系统中,凡是要进行中断处理和系统调用时,都将涉及到进程上下文的保存和恢复,此时系统所保存和恢复的是同属于一个进程的上下文。而在进程调度之后实现进程分派时,所涉及的是进程上

    注意事项

    本文(UNIX的进程管理.ppt)为本站会员(牧羊曲112)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开