操作系统-1:进程的简单介绍


前言

在传统的操作系统中,程序并不能独立运行,作为资源分配和独立运行的基本单位都是进程。操作系统所具有的四大特征也都是基于进程而形成的,并可从进程的观点来研究操作系统。显然,在操作系统中,进程是一个极其重要的概念。


在未配置 OS 的系统中,程序的执行方式是顺序执行,即必须在一个程序执行完后,才允许另一个程序执行;在多道程序环境下,则允许多个程序并发执行。程序的这两种执行方式间有着显著的不同。也正是程序并发执行时的这种特征,才导致了在操作系统中引入进程的概念。因此,这里有必要先对程序的顺序执行和并发执行方式做简单的描述。
  • 程序的顺序执行
    通常可以把一个应用程序分成若干个程序段,在各程序段之间,必须按照某种先后次序顺序执行,仅当前一操作(程序段)执行完后,才能执行后继操作。例如,在进行计算时,总须先输入用户的程序和数据,然后进行计算,最后才能打印计算结果。
    在这里插入图片描述
    程序顺序执行时的特征:
    (1) 顺序性:处理机的操作严格按照程序所规定的顺序执行,即每一操作必须在上一个操作结束之后开始。
    (2) 封闭性:程序是在封闭的环境下执行的,即程序运行时独占全机资源,资源的状态(除初始状态外)只有本程序才能改变它。程序一旦开始执行,其执行结果不受外界因素影响
    (3) 可再现性:只要程序执行时的环境和初始条件相同,当程序重复执行时,不论它是从头到尾不停顿地执行,还是“停停走走”地执行,都将获得相同的结果。
    程序顺序执行时的特性,为程序员检测和校正程序的错误带来了很大的方便。
  • 程序的并发执行
    在图 2-1 中的输入程序、计算程序和打印程序三者之间,存在着 Ii→Ci→Pi 这样的前趋关系,以至对一个作业的输入、计算和打印三个操作,必须顺序执行,但并不存在 Pi→Ii+1的关系,因而在对一批程序进行处理时,可使它们并发执行。
    在这里插入图片描述在该例中存在下述前趋关系:
    在这里插入图片描述程序并发执行时的特征:
  1. 间断性
    程序在并发执行时,由于它们共享系统资源,以及为完成同一项任务而相互合作,致使在这些并发执行的程序之间,形成了相互制约的关系。相互制约将导致并发程序具有“执行—暂停—执行”这种间断性的活动规律。
  2. 失去封闭性
    程序在并发执行时,是多个程序共享系统中的各种资源,因而这些资源的状态将由多个程序来改变,致使程序的运行失去了封闭性。这样,某程序在执行时,必然会受到其它程序的影响。
  3. 不可再现性
    程序在并发执行时,由于失去了封闭性,也将导致其再失去可再现性。

一、进程是什么?

1.进程的特征和定义

在多道程序环境下,程序的执行属于并发执行,此时它们将失去其封闭性,
并具有间断性及不可再现性的特征。这决定了通常的程序是不能参与并发执行的,因为程序执行的结果是不可再现的。这样,程序的运行也就失去了意义。为使程序能并发执行,且为了对并发执行的程序加以描述和控制,人们引入了“进程”的概念。

  1. 结构特征
    通常的程序是不能并发执行的。为使程序(含数据)能独立运行,应为之配置一进程控制块,即 PCB(Process Control Block);而由程序段、相关的数据段和 PCB 三部分便构成了进程实体。在早期的 UNIX 版本中,把这三部分总称为“进程映像”。值得指出的是,在许多情况下所说的进程,实际上是指进程实体,例如,所谓创建进程,实质上是创建进程实体中的 PCB;而撤消进程,实质上是撤消进程的 PCB。
  2. 动态性
    进程的实质是进程实体的一次执行过程,因此,动态性是进程的最基本的特征。动态性还表现在:“它由创建而产生,由调度而执行,由撤消而消亡”。可见,进程实体有一定的生命期,而程序则只是一组有序指令的集合,并存放于某种介质上,其本身并不具有运动的含义,因而是静态的
  3. 并发性
    这是指多个进程实体同存于内存中,且能在一段时间内同时运行。并发性是进程的重要特征,同时也成为 OS 的重要特征。引入进程的目的也正是为了使其进程实体能和其它进程实体并发执行;而程序(没有建立 PCB)是不能并发执行的。
  4. 独立性
    在传统的 OS 中,独立性是指进程实体是一个能独立运行、独立分配资源和独立接受调度的基本单位。凡未建立 PCB 的程序都不能作为一个独立的单位参与运行
  5. 异步性
    这是指进程按各自独立的、 不可预知的速度向前推进,或说进程实体按异步方式运行。
    曾有许多人从不同的角度对进程下过定义,其中较典
    型的进程定义有:
    (1) 进程是程序的一次执行。
    (2) 进程是一个程序及其数据在处理机上顺序执行时所发生的活动。
    (3) 进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。
    在引入了进程实体的概念后,我们可以把传统 OS 中的进程定义为:“进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位”

2.进程的3种状态

  1. 就绪(Ready)状态
    当进程已分配到除 CPU 以外的所有必要资源后,只要再获得 CPU,便可立即执行,进程这时的状态称为就绪状态。在一个系统中处于就绪状态的进程可能有多个,通常将它们排成一个队列,称为就绪队列。
  2. 执行状态
    进程已获得 CPU,其程序正在执行。在单处理机系统中,只有一个进程处于执行状态;在多处理机系统中,则有多个进程处于执行状态。
  3. 阻塞状态
    正在执行的进程由于发生某事件而暂时无法继续执行时,便放弃处理机而处于暂停状态,亦即进程的执行受到阻塞,把这种暂停状态称为阻塞状态,有时也称为等待状态或封锁状态。致使进程阻塞的典型事件有:请求 I/O,申请缓冲空间等。通常将这种处于阻塞状态的进程也排成一个队列。有的系统则根据阻塞原因的不同而把处于阻塞状态的进程排成多个队列。

处于就绪状态的进程,在调度程序为之分配了处理机之后,该进程便可执行,相应地,它就由就绪状态转变为执行状态。正在执行的进程也称为当前进程,如果因分配给它的时间片已完而被暂停执行时,该进程便由执行状态又回复到就绪状态;如果因发生某事件而使进程的执行受阻(例如,进程请求访问某临界资源,而该资源正被其它进程访问时),使之无法继续执行,该进程将由执行状态转变为阻塞状态。图 2-5 示出了进程的三种基本状态以及各状态之间的转换关系。
在这里插入图片描述

  • 挂起状态
    引入挂起状态的原因:
    在不少系统中进程只有上述三种状态,但在另一些系统中,又增加了一些新状态,最重要的是挂起状态。引入挂起状态的原因有:
    (1) 终端用户的请求。当终端用户在自己的程序运行期间发现有可疑问题时,希望暂时使自己的程序静止下来。亦即,使正在执行的进程暂停执行;若此时用户进程正处于就绪状态而未执行,则该进程暂不接受调度,以便用户研究其执行情况或对程序进行修改。把这种静止状态称为挂起状态。
    (2) 父进程请求。有时父进程希望挂起自己的某个子进程,以便考查和修改该子进程,或者协调各子进程间的活动。
    (3) 负荷调节的需要。当实时系统中的工作负荷较重,已可能影响到对实时任务的控制时,可由系统把一些不重要的进程挂起,以保证系统能正常运行。
    (4) 操作系统的需要。操作系统有时希望挂起某些进程,以便检查运行中的资源使用情况或进行记账。

3.进程的创建

  1. 引起创建进程的事件
    在多道程序环境中,只有(作为)进程(时)才能在系统中运行。因此,为使程序能运行,就必须为它创建进程。导致一个进程去创建另一个进程的典型事件,可有以下四类:
    (1) 用户登录。在分时系统中,用户在终端键入登录命令后,如果是合法用户,系统将为该终端建立一个进程,并把它插入就绪队列中。
    (2) 作业调度。在批处理系统中,当作业调度程序按一定的算法调度到某作业时,便将该作业装入内存,为它分配必要的资源,并立即为它创建进程,再插入就绪队列中。
    (3) 提供服务。当运行中的用户程序提出某种请求后,系统将专门创建一个进程来提供用户所需要的服务,例如,用户程序要求进行文件打印,操作系统将为它创建一个打印进程,这样,不仅可使打印进程与该用户进程并发执行,而且还便于计算出为完成打印任务所花费的时间。
    (4) 应用请求。在上述三种情况下,都是由系统内核为它创建一个新进程;而第 4 类事件则是基于应用进程的需求,由它自己创建一个新进程,以便使新进程以并发运行方式完成特定任务。例如,某应用程序需要不断地从键盘终端输入数据,继而又要对输入数据进行相应的处理,然后,再将处理结果以表格形式在屏幕上显示。该应用进程为使这几个操作能并发执行,以加速任务的完成,可以分别建立键盘输入进程、表格输出进程。
  2. 创建进程
    一旦操作系统发现要求创建新进程的事件后,便调用进程创建原语 Creat( )按下述步骤创建一个新进程。
    (1) 申请空白 PCB。为新进程申请获得惟一的数字标识符,并从 PCB 集合中索取一个空白 PCB。
    (2) 为新进程分配资源。为新进程的程序和数据以及用户栈分配必要的内存空间。显然,此时操作系统必须知道新进程所需内存的大小。对于批处理作业,其大小可在用户提出创建进程要求时提供。若是为应用进程创建子进程,也应是在该进程提出创建进程的请求中给出所需内存的大小。对于交互型作业,用户可以不给出内存要求而由系统分配一定的空间。如果新进程要共享某个已在内存的地址空间(即已装入内存的共享段),则必须建立相应的链接。
    (3) 初始化进程控制块。PCB 的初始化包括:① 初始化标识信息,将系统分配的标识符和父进程标识符填入新 PCB 中;② 初始化处理机状态信息,使程序计数器指向程序的入口地址,使栈指针指向栈顶;③ 初始化处理机控制信息,将进程的状态设置为就绪状态或静止就绪状态,对于优先级,通常是将它设置为最低优先级,除非用户以显式方式提出高优先级要求。
    (4) 将新进程插入就绪队列,如果进程就绪队列能够接纳新进程,便将新进程插入就绪队列。

二、什么是线程

如果说,在操作系统中引入进程的目的,是为了使多个程序能并发执行,以提高资源利用率和系统吞吐量,那么,在操作系统中再引入线程,则是为了减少程序在并发执行时所付出的时空开销,使 OS 具有更好的并发性。为了说明这一点,我们首先来回顾进程的两个基本属性: ① 进程是一个可拥有资源的独立单位;② 进程同时又是一个可独立调度和分派的基本单位。正是由于进程有这两个基本属性,才使之成为一个能独立运行的基本单位,从而也就构成了进程并发执行的基础。然而,为使程序能并发执行,系统还必须进行一系列操作:1) 创建进程、2) 撤消进程、3) 进程切换

线程具有许多传统进程所具有的特征,所以又称为轻型进程(Light-Weight Process)或进
程元,相应地把传统进程称为重型进程(Heavy-Weight Process),传统进程相当于只有一个线
程的任务。在引入了线程的操作系统中,通常一个进程都拥有若干个线程,至少也有一个线程

1.线程的属性
在多线程 OS 中,通常是在一个进程中包括多个线程,每个线程都是作为利用 CPU 的
基本单位,是花费最小开销的实体。线程具有下述属性。
(1) 轻型实体。线程中的实体基本上不拥有系统资源,只是有一点必不可少的、 能保证其独立运行的资源,比如,在每个线程中都应具有一个用于控制线程运行的线程控制块TCB,用于指示被执行指令序列的程序计数器,保留局部变量、少数状态参数和返回地址等的一组寄存器和堆栈。
(2) 独立调度和分派的基本单位。在多线程 OS 中,线程是能独立运行的基本单位,因而也是独立调度和分派的基本单位。由于线程很“轻”,故线程的切换非常迅速且开销小。
(3) 可并发执行。在一个进程中的多个线程之间可以并发执行,甚至允许在一个进程中的所有线程都能并发执行;同样,不同进程中的线程也能并发执行。
(4) 共享进程资源。在同一进程中的各个线程都可以共享该进程所拥有的资源,这首先表现在所有线程都具有相同的地址空间(进程的地址空间)。这意味着线程可以访问该地址空间中的每一个虚地址;此外,还可以访问进程所拥有的已打开文件、定时器、信号量机构等。

2.线程的状态
(1) 状态参数。
在 OS 中的每一个线程都可以利用线程标识符和一组状态参数进行描述。状态参数通常有这样项:① 寄存器状态,它包括程序计数器 PC 和堆栈指针中的内容;② 堆栈,在堆栈中通常保存有局部变量和返回地址;③ 线程运行状态,用于描述线程正处于何种运行状态;④ 优先级,描述线程执行的优先程度;⑤ 线程专有存储器,用于保存线程自己的局部变量拷贝;⑥ 信号屏蔽,即对某些信号加以屏蔽。
(2) 线程运行状态。
如同传统的进程一样,在各线程之间也存在着共享资源和相互合作的制约关系,致使线程在运行时也具有间断性。相应地,线程在运行时也具有下述三种基本状态: ① 执行状态,表示线程正获得处理机而运行;② 就绪状态,指线程已具备了各种执行条件,一旦获得 CPU 便可执行的状态;③ 阻塞状态,指线程在执行中因某事件而受阻,处于暂停执行时的状态。

三、Linux中的进程

以一个简单的C程序为例,说明其如何被操作系统当作进程执行的。
在这里插入图片描述
当运行程序,便创建了一个进程,并且从从内存中分配了必要的内存资源。CPU中有寄存器,各种寄存器分工不同。寄存器从内存中读取数据,并完成计算。
在这里插入图片描述对上述的程序,使用底层汇编语言,查看到底是怎么运行的
在这里插入图片描述

1.进程是什么样的

****进程的数据结构

在这里插入图片描述

****进程的状态转换

在这里插入图片描述
休眠有两种相关的进程状态:TASK_INTERRUPTIBLE 和TASK_UNINTERRUPTIBLE。
它们的不同之处不是处于TASK_UNINTERRUPTIBLE状态的进程会忽略信号,而是处于TASK_INTERRUPTIBLE状态的进程如果收到信号会被唤醒并处理信号(然后再次进入等待睡眠状态)。两种状态的进程位于同一个等待队列上,等待某些事件,不能够运行。

****Linux中进程文件存储目录 /proc

每一个编号对应一个进程,存储进程文件。(Linux中一切皆文件)
在这里插入图片描述

2.Linux中创建进程

一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。

fork()函数是创建子进程的函数。函数的返回值有两个。一个返回值为0 ,表示创建了子进程,一个返回值大于0,表示当前程序的进程,且这个大于0的数值就表示创建子进程的进程的pid。

在这里插入图片描述

该程序运行后会产生两个分支,一个分支是新创建的子进程执行分支,它会打印自己的pid以及父进程的pid。另一个分支是原进程的分支,也会打印自己的pid以及父进程的pid。该程序运行结果为:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值