《现代操作系统》之 进程与线程

第二章  进程与线程

2.1进程

    操作系统中最核心的概念是进程,它是对正在运行程序的一个抽象,包括操作系统。一个进程就是一个正在执行程序的实例,包括程序计数器、寄存器和变量的当前值。下图中有四个进程,但是只有一个物理程序计数器。在执行其中某个程序时,例如执行A进程,此时进程A的逻辑程序计数器就会被加载到物理程序计数器中。

《现代操作系统》之 进程与线程

并且在实际的执行当中,只有一个程序在执行。虽然现在多核的CUP盛行,但是即使是多核的CPU每个核就只能运行一个进程。而实现并行操作,实际上就是不停地切换不同的进程,使用户感觉上像是多个程序在同时执行(每个进程间的切换时间很短且很频繁)。所以实际上我们在对进程编程时绝对不可以做任何时序上的假设。

    “单个进程可以被若干个进程共享,它使用某种调度算法决定何时停止一个进程的工作,并转向另一个进程提供服务。”而同一个程序打开两次,算作是两个进程。这点需要额外注意。

2.1.2创建进程

    有以下4中情况会导致进程的创建:

  1. 系统初始化。
  2. 执行正在运行的进程所调用的进程创建系统调用。
  3. 用户请求创建一个进程。
  4. 一个批处理作业的初始化。

新进程都是由一个已存在的进程由于工作需要而创建的,其使用创建进程的系统调用来创建新的进程。在Unix系统中,fork()系统调用是用来创建新进程的。在调用这个系统调用后,两个进程(父进程和子进程)会拥有相同的存储映像、同样的环境字符串和同样的代开文件。子进程接着执行execve或一个类似的系统操作后,可以修改子进程存储映像并运行一个新的程序。其实实际上就是把所需要在该子进程中执行的代码复制到该子进程的存储映像中。

    在创建新的进程后,子进程和父进程的地址空间是不同的。但是需要强调的是,子进程的地址空间是父进程的地址空间的一个副本。这两个进程之间的部分资源是共享的,如:打开的文件等。但是程序计数器、寄存器等资源是互不相关的。

2.1.3  进程的终止

    进程的终止发生在以下4种情况:

  1. 正常退出(自愿的)。
  2. 出错退出(自愿的)。
  3. 严重错误(非自愿的)。
  4. 被其他进程杀死(非自愿的)。

2.1.5进程的状态

  1. 运行态(该时刻进程实际占用CPU)
  2. 就绪态(可运行,但是因为其他进程正在执行而暂停运行)
  3. 阻塞态(除非某种外部事件发生,否则进程不能运行)

《现代操作系统》之 进程与线程

在操作系统发现进程不能进行下去时,发生转换1。转换2和3是由进程调度程序引起的,进程调度程序是操作系统的一部分。当操作系统认为某个进程运行的时间足够久了,那么操作系统会将当前运行的程序切换到就绪态,让另一个处于就绪态的进程开始执行。另外,在等待例如外部键盘输入时,进程会被切换到阻塞态,一旦完成数据的输入会直接切换到运行态。

2.1.6  进程的实现

    在进程的运行的过程当中,操作系统需要去维护一张进程表。每个进程占用一个进程表项。每个表项包括程序计数器、堆栈指针、内存分配情况、所打开文件的状态,以及其他在进程由运行态切换到就绪态或阻塞态时必须保存的信息,从而保证该进程在随后启动后能够正确运行。

《现代操作系统》之 进程与线程