进程的来由

81 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第21天,点击查看活动详情

IBM在20世纪设计的多道批处理程序中没有进程(process),人们使用工作(job)这个术语,后来的设计人员慢慢启用进程这个术语。顾名思义,进程是执行中的程序,即一个程序加载到内存后变成了进程,公式表达如下。

进程=程序+执行

在计算机的发展历史过程中,为什么需要进程呢? 早期,整个操作系统只运行一个程序,其CPU利用率的低下程度可想而知。为了提高CPU利用率,人们设计了在一台计算机中加载多个程序到内存中并让它们并发运行的方案。每个加载到内存中的程序称为进程,操作系统管理着多个进程并发执行。进程会认为自己独占CPU,这是很重要的抽象。 若没有进程,操作系统就会退回单道程序操作系统了。进程的抽象是为了提高CPU的利用率,任何的抽象都需要一个物理基础,进程的物理基础便是程序。程序在运行之前需要有一个安身之地,这就要求操作系统在装载程序之前要分配合适的内存。此外,操作系统还需要小心翼翼地处理多个进程共享同一块物理内存时可能引发的冲突问题。 作者在10年前购买的笔记本电脑还是奔腾单核的处理器,但依然可以很流畅地同时做很多事情,如边听音乐边使用Word软件处理文字,还可以用邮箱客户端收发邮件等。其实CPU在某一个瞬间只能运行一个进程,但是在一段时间内,它可以运行多个进程,这样就让人们产生了并行的错觉,这就是常说的“伪并行”。 假设有一个只包含3个进程的简易操作系统,这3个进程都需要装载到系统的物理内存中并运行,图7.1(a)~(c)分别从物理视角、逻辑视角和时序视角展示了进程模型。进程和程序之间的关系是比较微妙的,程序是用于描述某件事情的一些操作序列或者算法,而进程是某种类型的活动,它包含程序、输入、输出以及状态等。如果把做菜看作进程,那么做菜的工序可以被看作程序,大厨可以被看作处理器,厨房可以被看作运行环境,厨房里有需要的食材、调料以及烹饪工具等,大厨阅读菜谱、取各种原料、炒菜以及上菜等一系列动作的总和可以理解为一个进程。假设在炒菜的过程中,为了接听一个紧急的电话,大厨会先记录一下现在菜做到哪一步了(保存进程的当前状态),那么这个接听电话的动作就是另一个进程了。这相当于处理器从一个进程(做菜)切换到了另一个高优先级的进程(接电话)。等电话接完了,大厨继续执行原来做菜的工序。做菜和打电话是两个相互独立的进程,同一时刻只能做一件事情。 线程称为轻量级进程,它是操作系统调度的最小单元,通常一个进程可以拥有多个线程。线程和进程的区别在于进程拥有独立的资源空间(如进程地址空间),而线程则共享进程的资源空间。Linux内核并没有特别的调度算法或定义特别的数据结构来标识线程,线程和进程都使用相同的进程描述符数据结构。内核里使用clone()函数来创建线程,其工作方式和创建进程的fork()函数类似,但它会确定哪些资源和父进程共享,哪些资源为线程独享。在Linux内核中,线程对应一个进程描述符,而进程对应一个(单线程的进程)或者一组进程描述符(多线程的进程)。