进程
进程是计算机科学中最成功,最深刻的概念之一。
在我们运行一个程序时,通常会有这样一个假象,就好像我们的程序是当前唯一运行的程序一样,它是独占 CPU 和内存的,程序的指令在处理器上一条一条地执行,最后,我们的程序就好像内存中唯一一个对象,这些假象都是进程的概念给我们提供的。
- 一个独立的逻辑控制流,它提供一种假象,就好像我们的程序独立地使用处理器。
- 一个独立的私有地址空间,它提供一种假象,好像我们的程序独立地使用内存系统
逻辑控制流
处理器的一个物理控制流被分为三个逻辑流,每个进程一个。每个竖直的条表示逻辑流的一部分。三个逻辑流的执行是交错的。关键在于进程是轮流使用处理器的,每个进程执行它的流的一部分,然后被抢占 [暂时挂起] 。
并发
一个逻辑流在执行的时间上与另一个发生重叠,就称为并发流。多个流并发的执行称为并发。一个进程和多个进程轮流地运行称为多任务。一个进程执行它的部分逻辑流的每一时间段称为时间片。
私有地址空间
进程为每个程序提供一个假象,好像它单独地占用系统地址空间。进程为每个程序提供它自己私有的地址空间。 每个地址空间的底部是保留给用户的,通常包括栈,堆,数据和代码。地址空间的顶部是保留给内核的。

内核模式和用户模式
一个运行在内核模式的进程可以执行指令中的任何指令,访问系统中的任何内存空间。没有设置模式时,进程就处在用户模式,此时的进程不允许执行带有特权的指令,如停止处理器,发起一个 I/O 操作等。也不允许访问内核区的代码和数据。
上下文切换
操作系统的内核使用一种上下文切换的形式的控制流来实现多任务。内核会为每一个进程维持一个上下文,上下文就是内核重新启动一个被强占的进程说需要的状态。在进程执行的某些时刻,内核可以决定抢占当前进程,并重新开启一个先前被抢占了的进程,这种行为叫做调度,这个时候就会发生上下文切换。如果系统因为某个调用而发生阻塞,那么内核可以让这个进程休眠,切换到另一个进程。比如,一个 read 系统调用访问磁盘,内核可以选择上下文切换,运行另一个进程,而不是等待数据从磁盘到达。

创建和终止进程
进程一般有三种状态
- 运行。要么在 CPU 上运行,要么被等待执行且最终会被内核调度。
- 停止。进程的执行被挂起,且不会被调度。当收到某种信号时,才会被重新调度,然后再次运行。
- 终止。进程永远的停止了,一般进程停止有三个原因
- 收到一个信号,该信号终止进程
- 从主程序中返回
- 调用 exit 函数
在 unix 系统中,创建一个子进程是 fork 函数。新创建的子进程与父进程几乎但不完全相同,子进程可以得到与父进程用户虚拟地址空间相同的一份副本(独立地),包括代码、数据、栈和堆。子进程还能读写父进程打开的文件,他们之间最大的区别就是有不同的 PID。

child 2
- 相同但是独立的地址空间 父进程和子进程的地址空间都是相同的,他们的用户栈、堆、全局变量、代码都是一样的。所以,在第 6 行fork函数返回时,x在两个进程的值都是 1。然而,他们却都有独立的地址空间。后面,父进程与子进程对 x 的操作也都是独立的,这就是后面两个 x 的值不同。
