3.1 进程和进程相关的简单描述
3.1.1进程简单说明:
进程管理是操作系统最为关键的部分,它的设计和实现直接影响到整个系统的性能。在一个多进程的操作系统中,一个时间段内可以有多个进程“并发”执行。这样就避免了较为快速的cpu等待较为低速的I/O设备的情况,提高了cpu利用率,从而提高系统的性能。另一个方面,同时运行多个进程,就可以同时提供多种服务或者同时为更多的客户服务,这也是现代操作系统的基本任务。
进程是一个随执行过程不断变化的实体。和程序要包含指令和数据一样,进程也包含程序计数器和所有CPU寄存器的值,同时它的堆栈中存储着如子程序参数、返回地址以及变量之类的临时数据。当前的执行程序,或者说进程,包含着当前处理器中的活动状态。Linux是一个多处理操作系统。进程具有独立的权限与职责。如果系统中某个进程崩溃,它不会影响到其余的进程。每个进程运行在其各自的虚拟地址空间中,通过核心控制下可靠的通讯机制,它们之间才能发生联系。
进程在生命期内将使用系统中的资源。它利用系统中的CPU来执行指令,在物理内存来放置指令和数据。使用文件系统提供的功能打开并使用文件,同时直接或者间接的使用物理设备。Linux必须跟踪系统中每个进程以及资源,以便在进程间实现资源的公平分配。如果系统有一个进程独占了大部分物理内存或者CPU的使用时间,这种情况对系统中的其它进程是不公平的。
系统中最宝贵的资源是CPU,通常系统中只有一个CPU。Linux是一个多处理操作系统,它最终的目的是:任何时刻系统中的每个CPU上都有任务执行,从而提高CPU的利用率。如果进程个数多于CPU的个数,则有些进程必须等待到CPU空闲时才可以运行。多处理是的思路很简单;当进程需要某个系统资源时它将停止执行并等待到资源可用时才继续运行。单处理系统中,如DOS,此时CPU将处于空等状态,这个时间将被浪费掉。在多处理系统中,因为可以同时存在多个进程,所以当某个进程开始等待时,操作系统将把CPU控制权拿过来并交给其它可以运行的进程。调度器负责选择适当的进程来运行,Linux使用一些调度策略以保证CPU分配的公平性。
3.1.2 进程及作业
Linux系统上所有运行的东西都可以称之为一个进程。每个用户任务、每个系统管理守护进程,都可以称之为进程。Linux用分时管理方法使所有的任务共同分享系统资源。我们所关心的是如何去控制这些进程,让它们能够很好地为用户服务。
进程与程序是有区别的,进程不是程序,虽然它由程序产生。程序只是一个静态的指令集合,不占系统的运行资源;而进程是一个随时都可能发生变化的、动态的、使用系统运行资源的程序。而且一个程序可以启动多个进程。
进程和作业的概念也有区别。一个正在执行的进程称为一个作业,而且作业可以包含一个或多个进程,尤其是当使用了管道和重定向命令。
作业控制指的是控制正在运行的进程的行为。比如,用户可以挂起一个进程,等一会儿再继续执行该进程。shell将记录所有启动的进程情况,在每个进程过程中,用户可以任意地挂起进程或重新启动进程。作业控制是许多shell(包括bash和tcsh)的一个特性,使用户能在多个独立 作业间进行切换。
例如,当用户编辑一个文本文件,并需要中止编辑做其他事情时,利用作业控制,用户可以让编辑器暂时挂起,返回shell提示符开始做其他的事情。其他事情做完以后,用户可以重新启动挂起的编辑器,返回到刚才中止的地方,就象用户从来没有离开编辑器一样。这只是一个例子,作业控制还有许多其他实际的用途。
3.1.3进程的切换
进程的切换包括3个层次:
(1) 用户数据的保存 包括正文段(TEXT),数据段(DATA,BSS),堆栈段(STACK),共享内存段(SHARED MEMORY)的保存。
(2) 寄存器数据的保存 包括 PC(Program couter,指向下一条要执行的指令的地址),PSW(Processor status word,处理机状态字),SP(Stack pointer,栈指针),PCBP(Pointer of process control block,进程控制块指针),FP(Frame pointer,指向栈中一个函数的 Local 变量的首地址),P( Augument pointer,指向栈中函数调用的实参位置),ISP(Interrupt stack pointer,中断栈指针),以及其他通用寄存器等。
(3) 系统级的保存 包括 Proc ,u,虚拟存储空间管理表格,中断处理栈。以便于该进程再一次得到 CPU 时间片时能正常运行下去。
3.1.4多进程系统具有以下一些突出的特点:
(1). 并行化 一件复杂的事件是可以分解成若干个简单事件来解决的,这在程序员的大脑中早就形成了这种概念,首先将问题分解成一个个小问题,将小问题再细分,最后在一个合适的规模上做成一个函数。在软件工程中也是这样。如果我们以图的方式在思考,一些小问题的计算可以互不干扰,而且可以同时处理,而在关键点则需要统一在一个地方来处理,这样的程序的运行,至少从人的时间观念上来说是这样的。而每个小问题的计算又比较简单。
(2). 简单有序 这样的程序对于程序员来说不亚于管理一班人,程序员为每个进程设计好相应的功能,并通过一定的通信机制将它们有机地结合在一起,对每个进程的设计是简单的,只是总控部分小心应付,就可完成整个程序的施工。
(3). 互不干扰 这个特点是操作系统的特点,各个进程相对独立,不会串位。
(4). 事务化 比如在数据电话查询中,将程序设计成一个进程只处理一次查询即可,即完成一个事务。当对话查询开始时,产生这样一个进程处理这次查询;另一个电话进来时,主控程序又产生一个这样的进程来进行处理,每个进程完成查询任务后消失。这样的编程很简单,只要做一次查询的程序就可以了。
3.2 Linux下的进程
3.2.1 Linux下的进程数据结构:
为了让Linux来管理系统中的进程,每个进程用一个task_struct数据结构来表示(任务与进程在Linux中可以混用)。数组task包含指向系统中所有task_struct结构的指针。
这意味着系统中的最大进程数目受task数组大小的限制,缺省值一般为512。创建新进程时,Linux将从系统内存中分配一个task_struct结构并将其加入task数组。当前运行进程的结构用current指针来指示。
Linux还支持实时进程。这些进程必须对外部时间作出快速反应,系统将区分对待这些进程和其他进程。虽然task_struct数据结构庞大而复杂,但它可以分成一些功能组成部分:
State
进程在执行过程中会根据环境来改变state。Linux进程有以下状态:
Running
进程处于运行(它是系统的当前进程)或者准备运行状态(它在等待系统将CPU分配给它)。
Waiting
进程在等待一个事件或者资源。Linux将等待进程分成两类;可中断与不可中断。可中断等待进程可以被信号中断;不可中断等待进程直接在硬件条件等待,并且任何情况下都不可中断。
Stopped
进程被停止,通常是通过接收一个信号。正在被调试的进程可能处于停止状态。
Zombie
这是由于某些原因被终止的进程,但是在task数据中仍然保留task_struct结构。 它象一个已经死亡的进程。
Scheduling Information
调度器需要这些信息以便判定系统中哪个进程最迫切需要运行。
Identifiers
系统中每个进程都有进程标志。进程标志并不是task数组的索引,它仅仅是个数字。每个进程还有一个用户与组标志,它们用来控制进程对系统中文件和设备的存取权限。
Inter-Process Communication
Linux支持经典的Unix IPC机制,如信号、管道和信号灯以及系统V中IPC机制,包括共享内存、信号灯和消息队列。我们将在IPC一章中详细讨论Linux中IPC机制。
Links
Linux系统中所有进程都是相互联系的。除了初始化进程外,所有进程都有一个父进程。新进程不是被创建,而是被复制,或者从以前的进程克隆而来。每个进程对应的task_struct结构中包含有指向其父进程和兄弟进程(具有相同父进程的进程)以及子进程的指针。我们可以使用pstree 命令来观察Linux系统中运行进程间的关系:
init(1)-+-crond(98)
|-emacs(387)
|-gpm(146)
|-inetd(110)
|-kerneld(18)
|-kflushd(2)
|-klogd(87)
|-kswapd(3)
|-login(160)---bash(192)---emacs(225)
|-lpd(121)
|-mingetty(161)
|-mingetty(162)
|-mingetty(163)
|-mingetty(164)
|-login(403)---bash(404)---pstree(594)
|-sendmail(134)
|-syslogd(78)
`-update(166)
另外,系统中所有进程都用一个双向链表连接起来,而它们的根是init进程的task_struct数据结构。这 个链表被Linux核心用来寻找系统中所有进程,它对ps或者kill命令提供了支持。
3.2.2 Linux的多处理器系统中的调度
在Linux世界中,多CPU系统非常少见。但是Linux上已经做了很多工作来保证它能运行在SMP(对称多处理)机器上。Linux能够在系统中的CPU间进行合理的负载平衡调度。这里的负载平衡工作比调度管理器所做的更加明显。
在多处理器系统中,人们希望每个处理器总处与工作状态。当处理器上的当前进程用完它的时间片或者等待系统资源时,各个处理器将独立运行调度管理器。SMP系统中一个值得注意的问题是系统中不止一个idle进程。在单处理器系统中,idle进程是task数组中的第一个任务,在SMP系统中每个CPU有一个idle进程,同时每个CPU都有一个当前进程,SMP系统必须跟踪每个处理器中的idle进程和当前进程。
在SMP系统中,每个进程的task_struct结构中包含着当前运行它的处理器的编号以及上次运行时处理器的编号。把进程每次都调度到不同CPU上执行显然毫无意义,Linux可以使用processor_mask来使得某个进程只在一个或者几个处理器上运行:如果N位置位,则进程可在处理器N上运行。当调度管理器选择新进程运行时,它不会考虑一个在其processor_mask中在当前处理器位没有置位的进程。同时调度管理器将给予上次在此处理器中运行的进程一些优先权,因为将进程迁移到另外处理器上运行将带来性能的损失。
3.2.3 Linux下时钟和定时器
核心跟踪着进程的创建时间以及在其生命期中消耗的CPU时间。每个时钟滴答时,核心将更新当前进程在系统模式与用户模式下所消耗的时间(记录在jiffies中)。
除了以上记时器外,Linux还支持几种进程相关的时间间隔定时器。
进程可以使用这些定时器在到时时向它发送各种信号,这些定时器如下:
Real
此定时器按照实时时钟记数,当时钟到期时,向进程发送SIGALRM信号。
Virtual
此定时器仅在进程运行时记数,时钟到期时将发送SIGVTALRM信号。
Profile
此定时器在进程运行和核心为其运行时都记数。当到时时向进程发送SIGPROF信号。
以上时间间隔定时器可以同时也可以单独运行,Linux将所有这些信息存储在进程的task_struct数据结构中。通过系统调用可以设置这些时间间隔定时器并启动、终止它们或读取它们的当前值。Virtual和Profile定时器以相同方式处理。
每次时钟滴答后当前进程的时间间隔定时器将递减,当到时之后将发送适当的信号。
联系客服