进程的非正式定义很是简单:进程就是运行中的程序。程序自己是没有生命周期的,它只是存在磁盘上面的一些指令(也多是一些静态数据)。人们经常但愿同时运行多个程序,一个正常的系统可能会有上百个进程同时在运行。数据结构
操做系统经过虚拟化(virtualizing)CPU来提供这种假象。经过让一个进程只运行一个时间片,而后切换到其余进程,操做系统提供了存在多个虚拟CPU的假象。这就是时分共享(time sharing)CPU技术,容许用户如愿运行多个并发进程。潜在的开销就是性能损失,由于若是CPU必须共享,每一个进程的运行就会慢一点。并发
操做系统为正在运行的程序提供的抽象,就是所谓的进程(process)。正如咱们上面所说的,一个进程只是一个正在运行的程序。在任什么时候刻,咱们均可以清点它在执行过程当中访问或影响的系统的不一样部分,从而归纳一个进程。函数
为了理解构成进程的是什么,咱们必须理解它的机器状态(machine state):程序在运行时能够读取或更新的内容。进程的机器状态有一个明显组成部分,就是它的内存。指令存在内存中,正在运行的程序读取和写入的数据也在内存中。所以进程能够访问的内存(称为地址空间,address space)是该进程的一部分。性能
进程的机器状态的另外一部分是寄存器。许多指令明确地读取或更新寄存器,所以,它们对于执行该进程很重要。例如,程序计数器(ProgramCounter,PC)(有时称为指令指针,Instruction Pointer或IP)告诉咱们程序当前正在执行哪一个指令;相似地,栈指针(stack pointer)和相关的帧指针(frame pointer)用于管理函数参数栈、局部变量和返回地址。spa
最后,程序也常常访问持久存储设备。此类I/O信息可能包含当前打开的文件列表。操作系统
操做系统运行程序必须作的第一件事是将代码和全部静态数据(例如初始化变量)加载(load)到内存中,也即加载到进程的地址空间中。程序最初以某种可执行格式驻留在磁盘上。所以,将程序和静态数据加载到内存中的过程,须要操做系统从磁盘读取这些字节,并将它们放在内存中的某处。指针
将代码和静态数据加载到内存后,操做系统在运行此进程以前还须要执行其余一些操做。必须为程序的运行时栈(run-time stack或stack)分配一些内存。生命周期
操做系统也可能为程序的堆(heap)分配一些内存。在C程序中,堆用于显式请求的动态分配数据。程序经过调用malloc()来请求这样的空间,并经过调用free()来明确地释放它。进程
操做系统还将执行一些其余初始化任务,特别是与输入/输出(I/O)相关的任务。例如,在UNIX系统中,默认状况下每一个进程都有3个打开的文件描述符(file descriptor),用于标准输入、输出和错误。事件
经过将代码和静态数据加载到内存中,经过建立和初始化栈以及执行与I/O设置相关的其余工做,OS如今为程序执行搭好了舞台。而后它有最后一项任务:启动程序,在入口处运行,即main()。经过跳转到main()例程,OS将CPU的控制权转移到新建立的进程中,从而程序开始执行。
简而言之,进程能够处于如下3种(稳定)状态之一。
操做系统是一个程序,和其余程序同样,它有一些关键的数据结构来跟踪各类相关的信息。例如,为了跟踪每一个进程的状态,操做系统可能会为全部就绪的进程保留某种进程列表(process list),以及跟踪当前正在运行的进程的一些附加信息。操做系统还必须以某种方式跟踪被阻塞的进程。当I/O事件完成时,操做系统应确保唤醒正确的进程,让它准备好再次运行。
操做系统追踪进程的一些重要信息。对于中止的进程,寄存器上下文将保存其寄存器的内容。当一个进程中止时,它的寄存器将被保存到这个内存位置。经过恢复这些寄存器(将它们的值放回实际的物理寄存器中),操做系统能够恢复运行该进程。
除了运行、就绪和阻塞以外,还有其余一些进程能够处于的状态。有时候系统会有一个初始(initial)状态,表示进程在建立时处于的状态。另外,一个进程能够处于已退出但还没有清理的最终(final)状态(在基于UNIX的系统中,这称为僵尸状态)。
注:存储关于进程的信息的个体结构称为进程控制块(Process Control Block,PCB)。