操作系统(一):进程和线程

在这里插入图片描述

1. 进程的简介

在这里插入图片描述
(进程特征部分提示:由于异步性会导致并发进程执行结果的不确定性,所以操作系统需要提供"进程同步"机制来解决异步问题)

进程的定义

进程有一个定义:进程是程序的一次执行过程。
在这里插入图片描述
程序强调的是静态性,它只是安安静静的躺在外存(如硬盘)之中,而当双击运行这个程序时,该程序会被操作系统载入到内存,生成相应的进程;而进程强调的是动态性,CPU会不断访问内存,执行进程的指令,完成进程的所提出的任务,比如,你想用QQ和人聊天,你双击别人头像之后,屏幕会显示一个对话窗口,在这里"屏幕会显示一个对话窗口"就是QQ进程的一个任务。

进程实体

进程实体是主存中的进程形态。在主存里边,进程也是一段连续的存储空间,这个空间称作进程控制块,在进程控制块中有一些重要的信息:比如标识符、状态、优先级、程序计数器、内存指针、上下文数据、IO状态信息、记账信息等等的一些重要的信息

在这里插入图片描述
在计算机发展的早期,由于计算机内存只支持运行一道应用程序,于是我们可以把该进程的程序段和数据段放在固定的位置。但是随着计算机的发展,计算机可以支持多道程序并发运行了,操作系统构建了一个叫进程控制块(PCB)的数据结构来存放进程的各种信息。

进程实体 = PCB + 程序段 + 数据段。 (进程实体 别名 进程映像)。

注意: 严格来说,进程实体和进程并不一样,进程是进程实体的运行过程, 是系统进行资源分配和调度的一个独立单位。进程实体是静态的,而进程是动态的。不过,除非题目专门考察二者区别,否则可以认为进程实体就是进程。因此我们可以说:进程由程序段、数据段和PCB三部分组成。

PCB的存储信息与分类

PCB(Process Control Block,进程控制块):操作系统用于管理控制进程的一个专门的数据结构
分为两种方式,方式一:
在这里插入图片描述
方式二:
在这里插入图片描述

进程的组织方式

一个操作系统中通常由数十、数百乃至数千个PCB。为了对它们进行有效的管理,进程分链接和索引两种方式,对多个进程进行组织管理。

链接方式

按照进程的状态将PCB分为多个队列,操作系统持有各个队列的指针。
在这里插入图片描述
以上所有的信息都被放置于内存之中。阻塞队列可能还会被划分为因等待什么事件而阻塞。

索引方式

按照进程的状态将PCB建立几张索引表,操作系统持有各个索引表的指针。
在这里插入图片描述

以上所有的信息都被放置于内存之中。阻塞队列可能还会被划分为因等待什么事件而阻塞。

2.进程模型

一个支持多进程的多道程序系统非常有必要,比如我们的个人PC。对于许多多道程序系统,存在伪并行的概念
在这里插入图片描述
为了对迅速换进换出的进程进行跟踪,开发者开发了一种用于描述并行的概念模型(顺序进程),使得并行更容易理解和分析。

在进程模型中,所有计算机上运行的软件,通常也包括操作系统,被组织为若干顺序进程(sequential processes),简称为进程(process)。一个进程就是一个正在执行的程序的实例,进程也包括程序计数器、寄存器和变量的当前值。从概念上来说,每个进程都有各自的虎拟CPU,但是实际情况是 CPU 会在各个进程之间进行来回切换。
在这里插入图片描述
在任何一给定瞬间仅有一个进程真正运行
在这里插入图片描述
当同一个进程再次在CPU中运行时,其在CPU内部的运行时间往往也是不固定的。进程是某一类特定活动的总和,它有程序、输入输出以及状态。单个处理器可以被若干进程共享,它使用某种调度算法决定何时停止一个进程的工作,并转而为另外一个进程提供服务。另外需要注意的是,如果一个进程运行了两遍,则被认为是两个进程。

总结而言:进程模型有两个关键概念
  1. CPU 会在各个进程之间进行来回切换,在任何一给定瞬间仅有一个进程真正运行
  2. 单个处理器可以被若干进程共享,它使用某种调度算法决定何时停止一个进程的工作,并转而为另外一个进程提供服务

3.进程创建

大多数系统的进程能够并发执行,它们可以动态创建和删除。因此,操作系统必须提供机制,用于创建进程和终止进程。 所谓的创建进程, 实际上是创建进程实体中的PCB,而撤销进程,实际上是撤销进程实体的PCB。 (PCB是进程存在的唯一标志)

创建进程称为父进程,而新的进程称为子进程。每个新进程可以再创建其他进程,从而形成进程树。大多数的操作系统(包括 UNIX、Linux 和 Windows)对进程的识别采用的是唯一的进程标识符(pid),pid 通常是一个整数值。系统内的每个进程都有一个唯一 pid。

用一个linux系统树的例子来理解进程创建的概念:

在这里插入图片描述
图中进程init是所有用户进程的根进程或父进程。一旦系统启动后,进程init可以创建各种用户进程。

在图 1 中,kthreadd 和 sshd 为 init 的两个子进程。kthreadd 进程负责创建额外进程,以便执行内核任务(这里为 khelper 和 pdflush)。sshd 进程负责管理通过 ssh 连到系统的客户端。login 进程负责管理直接登录到系统的客户端。在这个例子中,客户已登录,并且使用 bash 外壳,它所分配的 pid 为 8416。采用 bash 命令行界面,这个进程还创建了进程 ps 和 emacs 编辑器。

父子进程间的关系

一般来说,当一个进程创建子进程时,该子进程需要一定的资源(CPU 时间、内存、文件、I/O 设备等)来完成任务。子进程可以从操作系统那里直接获得资源,也可以只从父进程那里获得资源子集。父进程可能要在子进程之间分配资源或共享资源(如内存或文件)。限制子进程只能使用父进程的资源,可以防止创建过多进程,导致系统超载。

除了提供各种物理和逻辑资源外,父进程也可能向子进程传递初始化数据(或输入)。例如,假设有一个进程,其功能是在终端屏幕上显示文件如 image.jpg 的状态。当该进程被创建时,它会从父进程处得到输入,即文件名称 image.jpg。通过这个名称,它会打开文件,进而写出内容。它也可以得到输出设备名称。

当进程创建新进程时,可有两种执行可能:

  1. 父进程与子进程并发执行。
  2. 父进程等待,直到某个或全部子进程执行完。

子进程的地址空间也有两种可能:

  1. 子进程是父进程的复制品(它具有与父进程同样的程序和数据)。
  2. 子进程加载另一个新程序。
unix操作系统创建进程的例子

在 UNIX 中,通过系统调用 fork(),可创建新进程。新进程的地址空间复制了原来进程的地址空间。这种机制允许父进程与子进程轻松通信。这两个进程(父和子)都继续执行处于系统调用 fork() 之后的指令,但有一点不同:对于新(子)进程,系统调用 fork() 的返回值为 0;而对于父进程,返回值为子进程的进程标识符(非零)。

父进程等待,直到某个或全部子进程执行完。

通常,在系统调用 fork() 之后,有个进程使用系统调用 exec(),以用新程序来取代进程的内存空间。系统调用 exec() 加载二进制文件到内存中(破坏了包含系统调用 exec() 的原来程序的内存内容),并开始执行。采用这种方式,这两个进程能相互通信,并能按各自方法运行。父进程能够创建更多子进程,或者如果在子进程运行时没有什么可做,那么它采用系统调用 wait() 把自己移出就绪队列,直到子进程终止。因为调用 exec() 用新程序覆盖了进程的地址空间,所以调用 exec() 除非出现错误,不会返回控制。
在这里插入图片描述
父进程等待子进程的完成。当子进程完成后(通过显示或隐式调用 exit()),父进程会从 wait() 调用处开始继续,并且结束时会调用系统调用 exit()。

fork()函数简介:译作派生、分支,是UNIX或类UNIX中的分叉函数,fork函数将运行着的程序分成2个(几乎)完全一样的进程,每个进程都启动一个从代码的同一位置开始执行的线程。这两个进程中的线程继续执行,就像是两个用户同时启动了该应用程序的两个副本。

exec族函数作用:在参数指定的各目录中搜寻可执行文件、调用进程内部执行一个可执行文件。可执行文件既可以是二进制文件,也可以是任何Linux下可执行的脚本文件。

父进程与子进程并发执行。

子进程可以不调用 exec(),而是继续作为父进程的副本来执行。在这种情况下,父进程和子进程会并发执行,并采用同样的代码指令。由于子进程是父进程的一个副本,这两个进程都有各自的数据副本。

Windows操作系统创建进程和UNIX不同

在这里插入图片描述

扩展:为什么说PCB是进程存在的唯一标志
首先来看PCB的作用:

PCB是系统为每个进程定义的一个数据结构,其作用是使程序(含数据)能独立运行;PCB使一个在多道程序环境下不能独立运行的程序(含数据)成为一个能独立运行的基本单位,一个能与其他进程并发执行的进程,因此PCB是为了保证程序的并发执行。创建进程,实质上是创建进程的PCB;而撤销进程,实质上是撤销进程的PCB。

其次来解释为什么PCB是进程存在的唯一标志

在系统调度到某进程后,要根据其PCB中所保存的处理机状态信息,设置该进程恢复运行的现场,并根据其PCB中的程序和数据的内存地址,找到其程序和数据;进程在执行过程中,当需要和与之合作的进程实现同步、通信或访问文件时,也都需要访问PCB;当进程由于某种原因而暂停执行时,又需将其断点的处理机环境保存在PCB中。可见,在进程的整个生命周期中,系统总是通过PCB对进程进行控制的,亦即系统是根据 进程的PCB感知该进程的存在的,所以,PCB是进程存在的唯一标志。

4.进程的终止

子进程请求终止 和 父进程终止子进程

当进程完成执行最后语句并且通过系统调用 exit() 请求操作系统删除自身时,进程终止。这时,进程可以返回状态值(通常为整数)到父进程(通过系统调用 wait())。所有进程资源,如物理和虚拟内存、打开文件和 I/O 缓冲区等,会由操作系统释放。

在其他情况下也会出现进程终止。进程通过适当系统调用(如 Windows 的 Terminate-Process()),可以终止另一进程。通常,只有终止进程的父进程才能执行这一系统调用。否则,用户可以任意终止彼此的作业。记住,如果终止子进程,则父进程需要知道这些子进程的标识符。因此,当一个进程创建新进程时,新创建进程的标识符要传递到父进程。

父进程终止子进程的原因

  1. 子进程使用了超过它所分配的资源。(为判定是否发生这种情况,父进程应有一个机制,以检查子进程的状态)。
  2. 分配给子进程的任务,不再需要。
  3. 父进程正在退出,而且操作系统不允许无父进程的子进程继续执行。

有些系统不允许子进程在父进程已终止的情况下存在。对于这类系统,如果一个进程终止(正常或不正常),那么它的所有子进程也应终止。这种现象,称为级联终止,通常由操作系统来启动。

实例

以 Linux 和 UNIX 系统为例:可以通过系统调用 exit() 来终止进程,还可以将退出状态作为参数来提供。

/* exit with status 1 */
exit(1);

事实上,在正常终止时,exit() 可以直接调用(如上所示),也可以间接调用(通过 main() 的返回语句)。

父进程可以通过系统调用 wait(),等待子进程的终止。系统调用 wait() 可以通过参数,让父进程获得子进程的退出状态;这个系统调用也返回终止子进程的标识符,这样父进程能够知道哪个子进程已经终止了:

pid_t pid;
int status;
pid = wait(festatus);

僵尸进程和孤儿进程的产生

当一个进程终止时,操作系统会释放其资源。不过,它位于进程表中的条目还是在的,直到它的父进程调用 wait();这是因为进程表包含了进程的退出状态。当进程已经终止,但是其父进程尚未调用 wait(),这样的进程称为僵尸进程。所有进程终止时都会过渡到这种状态,但是一般而言僵尸只是短暂存在。一旦父进程调用了 wait(),僵尸进程的进程标识符和它在进程表中的条目就会释放。

如果父进程没有调用 wait() 就终止,子进程就会成为孤儿进程。Linux 和 UNIX 对这种情况的处理是:将 init 进程作为孤儿进程的父进程。进程 init 定期调用 wait(),以便收集任何孤儿进程的退出状态,并释放孤儿进程标识符和进程表条目。

5.进程的层次结构

在一些系统中,当一个进程创建了其他进程后,父进程和子进程就会以某种方式进行关联。子进程它自己就会创建更多进程,从而形成一个进程层次结构。

UNIX 进程体系

在UNIX中,进程和它的所有子进程以及子讲程的子进程共同组成一个进程组。当用户从键盘中发出一个信号后,该信号被发送给当前与键盘相关的讲程组中的所有成员(它们通常是在当前窗口创建的所有活动进程)。每个进程可以分别捕获该信号、忽略该信号或采取默认的动作,即被信号kill 掉。

UNIX在启动时的初始化可以用来说明层次的作用。一个称为init 的特殊进程出现在启动映像中,当init进程开始运行时,它会读取一个文件,文件会告诉它有多少个终端。然后为每个终端创建一个新进程。这些进程等待用户登录。如果登录成功,该登录进程就执行一个shell 来等待接收用户输入指令,这些命令可能会启动更多的进程,以此类推。整个操作系统中所有的进程都肃属干一个单个以init为根的讲程树。

Windows 进程体系

相反,Windows 中没有进程层次的概念,Windows 中所有进程都是平等的,唯一类似于层次结构的是在创建进程的时候,父进程得到一个特别的令牌(称为句柄),该句柄可以用来控制子进程。然而,这个令牌可能也会移交给别的操作系统,这样就不存在层次结构了。而在UNIX 中,进程不能剥夺其子进程的进程权。(这样看来,还是Windows比较渣)。

6.进程的状态

进程状态切换图
在这里插入图片描述
上图涉及到的三种状态:

  1. 运行态,运行态指的就是进程实际占用CPU时间片运行时
  2. 就绪态,就绪态指的是可运行,但因为其他进程正在运行而处于就绪状态
  3. 阻塞态,除非某种外部事件发生,否则进程不能运行

上图涉及到的四种转换:

逻辑上来说,运行态和就绪态都表示进程可以运行,但是就绪态没有获得CPU时间分片;阻塞态表示进程不能运行,即使CPU空闲。

7.进程实现

参考:

【1】操作系统之进程 (五) — 进程、进程实体、PCB…
【2】进程的创建和终止(超详细)
【3】为什么说PCB是进程存在的唯一标志
【4】进程(四)exec函数
【5】操作系统(程序员cxuan编写).pdf --公众号获取

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值