进程概述
当一个可执行程序在现代系统上运行时,操作系统会提供一种假象——好像系统上只有这个程序在运行,看上去只有这个程序在使用处理器,主存和IO设备。
处理器看上去就像在不间断的一条接一条的执行程序中的指令,即改程序的代码和数据是系统存储器中唯一的对象。这些假象是通过进程的概念来实现的。
进程是操作系统对一个正在运行的程序的一种抽象。在一个系统上可以同时运行多个进程,而每个进程都好像在独占的使用硬件。而并发运行,则是说一个进程的指令和另一个进程的指令是交错执行的。
在大多数系统中,需要运行的进程数是多于可以运行他们的CPU个数的。
传统系统在一个时刻只能执行一个程序,而现在的多核处理器同时能够执行多个程序。
无论是在多核还是单核系统中,一个CPU看上去都像是在并发的执行多个进程,这是通过处理器在进程间切换来实现的。
操作系统实现这种交错执行的机制称为上下文切换。
操作系统保持跟踪进程运行所需的所有状态信息,这种状态,也就是上下文,它包括许多信息,例如PC和寄存器文件的当前值,以及主存的内容。
在任何一个时刻,单处理器系统都只能执行一个进程的代码。
当操作系统决定要把控制权从当前进程转移到某个新进程时,就会进行上下文切换,即保存当前进程的上下文,恢复新进程的上下文,然后将控制权传递到新进程,新进程就会从上次停止的地方开始
深入计算机系统一书中对上下文切换的表达如下图:
如果现在有两个并发的进程:外壳进程和hello进程。
开始只有外壳进程在运行,即等待命令行上的输入,当我们让他运行hello程序时,外壳通过调用一个专门的函数,即系统调用,来执行我们的请求,系统调用会将控制权传递给操作系统。
操作系统保存外壳进程的上下文,创建一个新的hello进程及其上下文,然后将控制权传递给新的hello进程。
hello进程终止后,操作系统恢复外壳进程的上下文,并将控制权传回给他,外壳进程将继续等待下一个命令行输入。
这里很重要的一个思想是:一个进程是某种类型的一个活动,他有程序,输入,输出以及状态。单个处理器可以被若干进程共享,它使用某种调度算法决定何时停止一个进程, 并转而为另一个进程提供服务。
进程
进程的经典定义就是一个执行中的程序的实例。
系统中的每个程序都是运行在某个进程的上下文中的。
上下文是由程序正确运行所需的状态组成的,这个状态包括存放在存储器中的程序的代码和数据,他的栈,通用目的寄存器的内容,程序计数器,环境变量以及打开文件描述符的集合。
每次用户通过向外壳输入一个可执行目标文件的名字,并运行一个程序时,外壳就会创建一个新的进程,然后在这个新进程的上下文中运行这个可执行目标文件。
应用程序也能够创建新进程,且在这个新进程的上下文中运行他们自己的代码或其他应用程序。
进程提供给应用程序的关键抽象:
- 一个独立的逻辑控制流,它提供一个假象,好像我们的程序独占的使用处理器
一个私有的地址空间,它提供一个假象,好像我们的程序独占地使用存储器系统
而实际上,进程是轮流使用处理器的。
每个进程执行他的流的一部分,然后被抢占,即暂时挂起,然后轮到其他进程。
对于一个运行在这些进程之一的上下文中的程序,他看上去就像是在独占的使用处理器。
用户模式和内核模式
为了使操作系用内核提供一个无懈可击的进程抽象,处理器必须提供一种机制,限制一个应用可以执行的指令以及它可以访问的地址空间范围。
处理器通常是用某个控制寄存器中的一个模式位来提供这种功能的,该寄存器描述了进程当前享有的特权。
当设置了模式位时,进程就运行在内核模式中,即超级用户模式。
一个运行在内核模式的进程可以执行指令集中的任何指令,并且可以访问系统中任何存储器位置。
没有设置模式位时ÿ