Linux系统架构.docx
《Linux系统架构.docx》由会员分享,可在线阅读,更多相关《Linux系统架构.docx(123页珍藏版)》请在冰豆网上搜索。
![Linux系统架构.docx](https://file1.bdocx.com/fileroot1/2023-1/21/d65e8dbe-81c5-4cfe-ac11-14d2229d8842/d65e8dbe-81c5-4cfe-ac11-14d2229d88421.gif)
Linux系统架构
Linux系统架构
Linux一个遵循操作系统界面标准的免费操作系统,在外表和性能上与UNIX非常接近,它以稳定性、可靠性、安全性和灵活性著称。
Linux操作系统可以在基于Intelx86系列处理器的个人计算机(PC)上运行,并能实现全部的UNIX特性,可以将一台普通的PC机变成一台功能强大的Unix工作站。
目前,Linux操作系统已得到越来越广泛的应用,例如科学工作者使用Linux作分布式计算,ISP使用Linux搭建各种Internet服务器,越来越多的软件公司宣布支持Linux。
同时,Linux是一个开放源代码的自由软件,用户可以无偿地得到它的源代码和大量的Linux应用程序,而且可以任意地修改和补充它们,这对用户学习、了解操作系统的内核非常有益。
Linux进程管理
Linux进程
进程在操作系统中执行特定的任务。
而程序是存储在磁盘上包含可执行机器指令和数据的静态实体。
进程或者任务是处于活动状态的计算机程序。
进程是一个随执行过程不断变化的实体。
和程序要包含指令和数据一样,进程也包含程序计数器和所有CPU寄存器的值,同时它的堆栈中存储着如子程序参数、返回地址及变量之类的临时数据。
当前的执行程序,或者说进程,包含着当前处理器中的活动状态。
Linux是一个多处理操作系统。
进程具有独立的权限与职责。
如果系统中某个进程崩溃,它不会影响到其余的进程。
每个进程运行在其各自的虚拟地址空间中,通过核心控制下可靠的通信机制,它们之间才能发生联系。
Linux运行模式、地址空间与上下文
运行Linux系统的计算机硬件至少需要提供两种运行模式:
高优先级的内核模式(特权模式)与低优先级的用户模式。
内核运行在高优先级,称之为内核态,其他外围软件包括编辑程序、X-Windows等都运行在低优先级,称之为用户态。
采用不同的执行模式是为了系统保护。
当用户进程需要完成特权模式下才能完成的某些功能时,必须严格按照系统调用提供的接口才能进入特权模式,然后执行调用所提供的有限的功能。
每一种运行态都有自己的堆栈,Linux中分为用户栈和核心栈。
采用特权模式进行保护的根本目的是对地址空间的保护,用户进程不能访问所有的地址空间,只有通过系统调用才能进入内核,访问受保护的那些地址空间的数据。
另外,进程与进程之间的地址空间也不能随便互访。
Linux通过虚存管理机制很好地实现了这种保护。
在虚存系统中,进程所使用的地址不直接对应物理的存储单元,每个进程都有自己的虚拟地址空间,对虚拟地址空间的引用通过地址变换机制转换成物理地址的引用。
虚拟地址空间分为两部分:
用户空间和系统空间。
在用户模式下只能访问用户空间,而在核心模式下可以访问用户空间和系统空间。
一个进程的上下文可以分为三个部分:
用户级上下文、寄存器上下文及系统级上下文。
用户级上下文有:
正文、数据、用户栈及共享存储区。
寄存器上下文有:
程序计数器PC(即CPU将执行的下条指令地址)、处理机状态寄存器、栈指针、通用寄存器。
系统级上下文有:
进程表
结构task_struct、存储表及页表和核心栈等。
全部的上下文信息组成了一个进程的运行环境。
当发生进程调度时,必须对全部上下文
信息进行切换,新调度的进程才能运行。
进程就是上下文集合的一个抽象概念。
Linux存储器管理
Linux文件系统
Linux设备管理
第8章 Linux进程管理
本章要点:
Linux进程
地址空间与上下文
进程控制块PCB
进程调度
进程通信:
信号、管道、消息队列、信号量、共享内存
Linux是一个多用户操作系统,支持分时处理和“软”实时处理。
Intel版本的Linux利用其
体系结构的保护模式和特权级等特征,将进程分为内核态和用户态两种级别。
中断和系统调
用是内核向用户提供服务的重要途径。
Linux的进程管理由进程控制块、进程调度、进程间通信等部分组成,它是Linux存储管
理、文件管理和设备管理的基础。
Linux系统中的进程包括交互进程、批处理进程和守护进程。
8.1 Linux进程
进程在操作系统中执行特定的任务。
而程序是存储在磁盘上包含可执行机器指令和数据
的静态实体。
进程或者任务是处于活动状态的计算机程序。
进程是一个随执行过程不断变化的实体。
和程序要包含指令和数据一样,进程也包含程
序计数器和所有CPU寄存器的值,同时它的堆栈中存储着如子程序参数、返回地址及变量之
类的临时数据。
当前的执行程序,或者说进程,包含着当前处理器中的活动状态。
Linux是一个多处理操作系统。
进程具有独立的权限与职责。
如果系统中某个进程崩溃,
它不会影响到其余的进程。
每个进程运行在其各自的虚拟地址空间中,通过核心控制下可靠
的通信机制,它们之间才能发生联系。
8.1.1 Linux运行模式、地址空间与上下文
运行Linux系统的计算机硬件至少需要提供两种运行模式:
高优先级的内核模式(特权模
式)与低优先级的用户模式。
内核运行在高优先级,称之为内核态,其他外围软件包括编辑程
序、X-Windows等都运行在低优先级,称之为用户态。
采用不同的执行模式是为了系统保护。
当用户进程需要完成特权模式下才能完成的某些功能时,必须严格按照系统调用提供的接口
才能进入特权模式,然后执行调用所提供的有限的功能。
每一种运行态都有自己的堆栈,
Linux中分为用户栈和核心栈。
采用特权模式进行保护的根本目的是对地址空间的保护,用户进程不能访问所有的地址第8章 Linux进程管理191
空间,只有通过系统调用才能进入内核,访问受保护的那些地址空间的数据。
另外,进程与进
程之间的地址空间也不能随便互访。
Linux通过虚存管理机制很好地实现了这种保护。
在虚
存系统中,进程所使用的地址不直接对应物理的存储单元,每个进程都有自己的虚拟地址空
间,对虚拟地址空间的引用通过地址变换机制转换成物理地址的引用。
虚拟地址空间分为两
部分:
用户空间和系统空间。
在用户模式下只能访问用户空间,而在核心模式下可以访问用户
空间和系统空间。
一个进程的上下文可以分为三个部分:
用户级上下文、寄存器上下文及系统级上下文。
用
户级上下文有:
正文、数据、用户栈及共享存储区。
寄存器上下文有:
程序计数器PC(即CPU
将执行的下条指令地址)、处理机状态寄存器、栈指针、通用寄存器。
系统级上下文有:
进程表
结构task_struct、存储表及页表和核心栈等。
全部的上下文信息组成了一个进程的运行环境。
当发生进程调度时,必须对全部上下文
信息进行切换,新调度的进程才能运行。
进程就是上下文集合的一个抽象概念。
8.1.2 Linux进程控制块
Linux系统中的进程称为任务。
该系统的进程控制块(ProcessControlBlock,PCB)用一个
称为task_struct的结构体来描述,具体定义可参看Linux源代码文件/include/linux/sched.c。
所有task_struct结构的指针形成一个数组task。
这意味着系统中的最大进程数目受task数组
大小的限制,其默认值一般为512个。
当建立新进程时,Linux将为新进程分配一个task_struct
结构,然后将指针保存在task数组中。
为了便于寻找,当前指针总是指向当前进程。
task_
struct结构非常庞大,包括以下一些信息。
1.状态信息
(1)状态种类
Linux内核在进程控制块中用state成员描述进程当前的状态(State),并明确定义以下五
种状态。
①task_running状态:
包含了基本状态中的执行和就绪两种状态,进程实际是正在运行还
是处于就绪状态准备运行,要靠当前是否占有CPU资源来区分。
②task_interruptible状态:
表示进程处于可中断的等待状态,也就是说处于等待队列的进
程,可以被其他进程产生的一个信号或一个硬件中断所唤醒,使进程的状态转变成task_run-
ning状态。
③task_uninterruptible状态:
表示进程处于不可中断的等待状态,不可中断的等待状态是
指等待的进程不能被其他进程产生的一个信号所唤醒或者说改变成另一个状态。
当进程打开
一个设备文件时,才会用到这种状态。
④task_zomble状态:
表示进程已中止执行,并且释放了运行时的大部分资源,但尚未释放
自己的进程控制块时所处的一种僵死状态。
⑤task_stopped状态:
表示进程的执行被暂停。
当一个进程被另一个进程监控时,任何信
号都可以把这个进程的状态改变成暂停状态。
(2)主要内核函数
Linux内核涉及一个进程执行状态转换的主要内核函数有以下几个。
①创建一个新进程的函数do_fork()。
②调度函数schedule()。
192操作系统原理与应用
③睡眠(将进程挂到相应等待队列中)函数,这些函数有:
sleep_on()函数和interruptible_
sleep_on()函数。
④唤醒函数wake_up()和中断唤醒函数wake_up_interruptible()。
⑤退出函数do_exit()。
图8-1所示为进程之间状态转换图。
图8-1 进程之间状态转换图
2.调度信息
调度信息用于进程调度(Scheduling),决定调度的次序。
3.进程标识号
(1)进程标识号
进程一旦创建,就由系统给定一个进程序号,叫做进程标识号(ProcessIdentifier,PID)。
这是一个不小于0的整数,它与系统中的进程是一一对应的。
以后系统对该进程的操作,都是
通过这个进程标识号来实现的。
(2)用户和组标识
Linux系统中有不同的用户和组标识(UserandGroupIdentifier),主要用来控制进程对系
统文件的访问权限,实现系统资源的安全访问。
Linux系统中所有的文件都有所有者和允许的
权限,这些权限描述了系统使用者对文件和目录的使用权。
基本的权限是读、写和可执行,这
些权限被分配给文件的所有者,同组用户和系统中的其他用户三类用户。
4.进程间通信信息
Linux支持典型的UNIX进程间通信(IPC)机制———信号、管道,也支持SYSTEMV通信机
制———共享内存、信号量和消息队列。
5.进程链信息
Linux中不存在完全独立的进程。
除初始化进程外,任一进程都有一个父进程。
每个新进第8章 Linux进程管理193
程都是从父进程中复制或克隆过来,都有一个进程链(Links)。
所以进程都有父进程和子进程
之间连接关系问题。
6.时钟和定时器信息
为追踪进程的创建时间和占用CPU时间,并统计当前进程在系统中及在用户状态下所花
费的时间,需要时钟和定时器(TimesandTimers)信息。
7.文件系统信息
进程可以随时打开和关闭文件,使用程序和数据,所以要有与文件系统(FileSystem)相关
的信息。
8.虚存信息
大多数的进程都拥有一些虚拟存储器,Linux内核需要跟踪记录这些虚拟存储器在实际物
理存储器上的地址,即虚拟内存(VirtualMemory)信息。
9.进程运行环境信息
是系统现运行状态的汇总,相当于通常CPU现场保留区。
8.2 进程调度
Linux中所有进程部分时间运行于用户模式,部分时间运行于系统模式。
如何支持这些模
式,底层硬件的实现各不相同,但是存在一种安全机制可以使它们在用户模式和系统模式之间
来回切换。
8.2.1 Linux系统的进程调度发生的时机
对于Linux系统,没有设置专门的调度进程,需要进程调度时,调用一个特定的调度函数
schedule()来完成该功能。
通常,Linux系统中进程调度发生的时机有以下几种。
①用户创建一新的进程时,系统把它加到就绪队列中,返回该进程的进程标识号。
这时,
调度函数开始执行,这样可以保证系统具有很好的响应特性。
②正在执行的进程申请资源或等待某个事件的发生,而得不到满足时,该进程进入等待
状态;当正在执行的进程完成了任务或得到特定的信号而退出,将转入僵死状态。
这两种进程
状态转换完成后,调用调度函数,选择新的进程分配给CPU。
③分时系统中,进程执行完一定的时间片后,调用调度函数释放CPU资源,选择新的进
程分配给CPU。
④Linux系统提供了两级保护,用户进程可以在用户态和核心态下运行。
具有不同的特
权级别,可以访问不同的地址空间。
用户进程可以在这两种模式之间进行切换,用户态通过中
断或函数调用就可以转入核心态,其中,中断是应进程外部发来信息的要求而转入核心态,函
数调用则是应进程内部要求转入核心态,而从核心态切换到用户态,则需要一定的硬件支持。
当进程从核心态返回到用户态时,将调用调度函数,发生调度。
8.2.2 Linux系统进程调度的工作
Linux内核调度管理程序在运行时将执行下面工作。
①处理内核中的工作。
调度程序运行底层处理程序并处理调度任务队列。
②处理当前进程。
在选定其他进程运行之前必须对当前进程进行一些处理。
如果当前194操作系统原理与应用
进程的调度策略是时间片轮转,则它被放回到运行队列;如果任务可中断且从上次被调度后接
收到了一个信号,则它的状态变为running;如果当前进程超时,则它的状态变为running;如果
当前进程的状态是running,则状态保持不变。
那些既不处于running状态,又不是可中断的进
程将会从运行队列中删除。
这意味着调度程序选择运行进程时不会将这些考虑在内。
③选择进程。
调度程序在运行队列中选择一个最迫切需要运行的进程。
普通进程的权值
是它的counter值,而实时进程则是counter值加上1000。
如果运行队列中存在实时进程,则将优
先运行实时进程。
如果系统中存在几个相同优先级的进程,这时当前运行进程已经用掉了一些
时间片,因此它将处在不利位置(其counter值已经变小),这样位于运行队列最前面的进程将优
先运行。
在存在多个相同优先级进程的平衡系统中,每个进程被依次执行,这就是时间片轮转
(RoundRobin,RR)策略。
然而,由于进程经常需要等待某些资源,运行顺序也常发生变化。
④进程交换。
如果系统选择其他进程运行,则必须将当前进程挂起,且开始执行新的进
程。
当挂起一进程时,该进程所涉及的机器状态,包括程序计数器(PC)和CPU存储器将保存
在进程的task_struct数据结构中,而即将运行的进程的task_struct状态将装入到机器中。
如果
当前进程或即将运行的进程使用了虚拟内存,则必须更新系统的内存页面页表。
8.2.3 Linux系统的进程调度策略
在Linux系统中,作业一旦提交,就直接进入内存,建立相应的进程,进入进程调度管理。
Linux系统中的内核级线程和进程在表示、管理调度方面没有差别、系统采用进程调度统一处
理进程和内核级线程。
下面主要就调度策略、优先级、普通进程和实时进程的调度策略来分别
讨论。
1.调度策略
Linux系统的调度程序就是内核中的schedule()函数,它的主要任务是在就绪队列run_
queue中选出一个进程并投入运行。
Linux系统提供了3种进程调度策略。
这3种策略可由用户通过宏定义来选择。
可使用
的调度策略见表8-1。
表8-1 调度策略
调度策略标志所代表的调度策略
#definesched_other普通的分时进程
#definesched_fifo先进先出的实时进程
#definesched_rr基于优先级的轮转算法(动态优先级调度)
#definesched_yield不是调度策略,表示进程让出CPU
内核把进程分为实时进程和普通进程两种。
实时进程中的所谓“实时”是“及时”或“马
上”的意思,显然实时进程要求系统的响应速度越快越好。
而非实时进程又称为普通进程,它
对响应时间的要求不是很严格。
显然,实时进程应该优先于普通进程获得CPU。
2.优先级
进程的优先级是一些短整数,代表每个进程相对获得CPU的权值。
因此,进程的优先级
越高,得到CPU的机会也就越大。
Linux内核又进一步把进程优先级分为以下3种。
第8章 Linux进程管理195
静态优先级:
所谓“静态”是指优先级被确定后,不随时间而改变。
静态优先级是由用
户确定的,因此只能由用户进行修改。
它表示该进程被允许执行时间片的大小。
动态优先级:
所谓“动态”是指在进程运行时,优先级的值随着时间片的减少而减小,当
它小于0时,调度程序可重新调度其他就绪进程运行。
因此动态优先级是指进程运行
的时间片中所剩余的时间量。
实时优先级:
该优先级只使用于实时进程,并且明确规定实时进程总是优先于非实时进
程。
它指明正在运行的进程自动把CPU交给其他哪一个进程。
Linux进程的优先级在task_struct结构中使用不同分量来表示:
静态优先级由分量priority
来表示,动态优先级由分量counter来表示,实时优先级由分量rt_priority来表示。
进程静态优先级priority是在进程建立时继承父进程的,用户可以通过系统调用nice()或
setpriority()来设置其值,除此之外,priority在一个进程整个运行期间其值保持不变。
在Linux
1.4版中,静态优先级的取值范围是1~35,普通用户使用nice()系统调用设置静态优先级
priority时只能在这个范围内设置。
其后的版本中新增的setpriority()系统调用允许超级用户
将一个进程的动态优先级counter定义为任意大的值。
当然,如果将一个进程的动态优先级
counter设得过大,系统将降级为一个单任务的操作系统。
用户可以通过系统调用sched_
setschedule()函数改变自己的调度策略,通过系统调用sys_setpriority()和sys_nice()改变其静
态优先级。
一旦进程变为实时进程,它的子孙进程也是实时进程。
3.普通进程的调度策略
对于普通进程即非实时进程,Linux的调度策略采用动态优先级调度算法(sched_other)。
这是一种经常被采用的进程调度算法,这种算法不设进程就绪队列。
进程调度子程序schded-
ule()总是选择动态优先级最高的进程来分配给其CPU,如图8-2所示。
图8-2 Linux的进程调度过程
动态优先级是通过task_struct结构中的counter分量定义的。
counter表示在抢占式中断
调度前该进程还能运行的时间,这个时间的单位是tick,即时钟中断的发生周期。
在Linux中,
一个tick是10毫秒。
即每隔10毫秒发生一次时钟中断。
因此,如果一个进程在某个时刻的
动态优先级是55。
那么该进程这次使用CPU至少还能再连续运行550毫秒,在此期间不能发
生抢占式中断调度。
即在此期间只能进行快中断处理,除非该进程因需等待I/O等原因而主
动退出运行态,否则不能被抢占式中断调度强迫退出运行态;如果某个时刻,系统中共有4个
就绪进程,它们的优先级分别是2,20,30,10,那么,调度程序显然会选中动态优先级为30的196操作系统原理与应用
那个进程来使用CPU。
从时间片的角度来看,Linux的时间片是动态时间片,同一时刻上不同
进程的时间片是不同的,同一进程在不同时刻的时间片也是不同的,Linux的进程调度算法总
是选中当前时刻时间片最大的那个进程来使用CPU。
进程动态优先级counter的值的产生和变化与进程静态优先级有关。
在进程建立时,进程动态优先级的值是从父进程(当时的值)继承的。
之后,在该进程存
在期间,进程动态优先级是变化的。
每当时钟中断发生时,当前运行进程的counter值减1,这
种递减过程会在下列两种情况下停止。
①当counter递减到0时,进程就会在时钟中断处理过程中,被迫从运行态进入就绪态。
系统中处于就绪态的进程,其进程动态优先级不一定全为0。
对于那些从运行态进入就绪态
的进程,其进程动态优先级一定为0;对于那些从等待态进入就绪态的进程,其进程动态优先
级通常不为0。
从运行态进入就绪态的进程,会在就绪态中一直保持动态优先级为0,这样,不
为0的那些进程会很快进入运行态,又很快进入等待状态或以0值进入就绪状态,直到系统中
的所有就绪态进程的动态优先级都为0,再在进程调度程序中被重新置为各自进程的静态优
先级的值,然后按动态优先级的值依次进入运行态运行。
②对于处于运行态的进程,可能在counter还没递减到0时,进程就因需等待某个事件的
发生而进入了等待态。
处于等待态的进程,其动态优先级通常逐渐增加,也可能不变,但不可
能减小。
从图8-2中可以看出CPU的调度过程。
请注意该过程的“N”这一分支,这一步是当所有
就绪进程的动态优先级都为0时,重新计算所有进程的动态优先级,所有就绪进程的动态优先
级都被设为该进程的静态优先级。
这一步有3点需要注意:
并不是当所有进程的动态优先级都递减到0时才一起这样做;
所有进程都参加了重新计算,包括就绪态进程和等待态进程;
并不是直接将静态优先级值赋给动态优先级,而是利用一个专用的计算公式给出Linux
进程的动态优先级的计算方法。
counter的计算公式为:
p->counter=(p->counter>>1)+p->priority
//p为每个进程的task结构指针
对每个进程,将该进程的动态优先级的值右移一位(即除以2后取整)后,再加上该进程
的静态优先级的值,就得到该进程的动态优先级的新值。
对就绪进程,实质上仍是直接赋值
(因为此时所有就绪进程的动态优先级已都为零)。
但对于处于等待态的进程来说,这个公式
表示等待态进程的动态优先级大于其静态优先级,但不会比静态优先级的两倍更大。
counter的这种变化带来了如下效果。
等待态进程会有较高的优先级,且处于等待态时间越长的进程,其进程动态优先级就越
高(直至等于其静态优先级两倍,此后便不再变化,直至进入运行态),这就意味着,I/O
较多的进程(通常从运行态退出时是进入等待态)会有较高的优先级。
计算较多的进程(通常从运行态退出时进入就绪态)会有较低的优先级,因为它不仅不
会像等待进程那样增加优先级,而且会在就绪态等待较长时间。
大多数操作系统都有调度队列,如Solaris和Windows2000/NT,调度算法都采用多重队列
动态优先级算法。
Linux中进程动态优先级的上述变化过程在一定程度上达到了多重队列调第8章 Linux进程管理197
度算法的效果。
4.实时进程的调度策略
对于实时进程,Linux系统使用两种调度策略:
先来先服务算法(FirstComeFirstServer,
FIFS)和时间片轮转法(RR)。
因为实时进程对时间响应要求较高,因此为了保证实时进程能
够优先于普通进程而运行,内核为实时进程增加了第三种优先级,称为实时优先级。
实时优先
级被保存在进程控制块PCB的rt_priority成员中,它是一个0~99的整数;实时进程使用静态
优先级priority常数和动态优先级counter完成的功能与普通进程相同,但是counter不作为实
时进程调度的依据,这与普通进程不同。
8.3 进程通信
进程间的信息交换称为进程通信。
进程互斥与同步就是一种进程间的通信方式。
操作系
统可以被看作是由各种进程组成的,如用户进程、系统进程、计算进程、打印进程等,这些进程
都具有各自的独立功能,且大多数由于外部需要而产生并执行。
通常,进程间的通信分为控制
信息的传送与大量信息的传送两种。
有时,将进程间控制信息的交换称为低级通信,而把进程
之间大批量数据的交换称为高级通信。
由于进程的互斥与同步交换的信息量较少且效率较
低,因此称这种通信方式为低级通信方式,相应地,也称P和