多道程序环境下,允许程序并发执行以共享系统资源,此时程序失去封闭性,具有间断性和不可再现行等特征。程序本身是一组静态的指令集合,无法描述程序在内存中的并发执行的各种情况(何时开始、结束、与其他进程交互等)。为此OS引入进程(Process)概念,以便更好的描述程序动态执行过程的性质乃至更好地支持和管理多道程序的并发执行,实现OS的并发性和共享性(两个最基本特征)。
进程具有动态性,是应用程序的运行过程,是系统进行资源分配和调度的最小单位,它可以申请和拥有系统资源。进程拥有代码和打开的文件资源、数据资源、独立的内存空间。
一个进程实体由程序段、相关数据段和PCB三部分组成。
程序段:进程运行的程序的代码;
相关数据段:存储程序运行过程中相关的数据;
PCB:Process Control Block,即进程控制块,是标志进程存在的唯一标识。
(1)动态性:是程序的一次执行,具有一定的声明周期,区别于静态的程序;
(2)并发性:引入进程的其中一个目的就是为了并发执行,提高资源利用率,指多个进程实体在一段时间内能够同时运行;
(3)独立性:进程是操作系统进行资源分配的基本单位,每个进程实体能够独立获得系统资源;
(4)异步性:由于进程之间相互制约,导致进程间断执行;
(5)结构性:每个进程实体由程序段、相关数据段和PCB三部分组成。
如下图所示,共5中状态,其中就绪、运行、阻塞是进程的基本状态,需重点掌握。
新建:进程创建
就绪:进程做好了准备,准备执行,等待分配处理机
运行:该进程正在执行;
阻塞:等待某事件发生才能执行,如等待I/O完成;
终止状态
(1)为新进程分配唯一的标识号,并申请空白的PCB;
(2)为新进程分配资源,如给新进程的程序段、数据、及用户栈分配内存空间。
(3)初始化PCB,包括处理机状态、进程的优先级等。
(4)将新进程插入就绪队列,等待执行。
fork()、vfork()、clone()都是Linux的系统调用。
(1)Fork()
特点:创造的子进程复制了父亲进程的资源,包括内存的内容task_struct内容。
优点:是子进程的执行独立于父进程,具有良好的并发性。
缺点:是两者的通信需要专门的通信机制,如pipe、fifo和system V等。
(2)vfork()
特点:函数创建的子进程与父进程共享数据段,完全运行在父进程的地址空间上,子进程对虚拟地址空间任何数据的修改都为父进程所见。创建的子进程后,父进程会被阻塞,直到子进程执行exec()和exit(),即子进程先于父进程执行。
优点:通过vfork() 可以减少不必要的开销,如果调用子程序仅仅是为了执行另一个程序,则此时对地址空间的复制是多余的。
缺点:不能并发执行,子进程必须先于父进程执行。
(3)clone()
fork()是全部复制,vfork()是共享内存,而clone()是则可以将父进程资源有选择地复制给子进程,而没有复制的数据结构则通过指针的复制让子进程共享,具体要复制哪些资源给子进程,由参数列表中的clone_flags来决定。另外,clone()返回的是子进程的pid。
①共享存储:在通信的进程之间存在可以直接访问的内存空间,通过对内存空间的读写操作是进程之间的信息交换。读写操作时,需要使用同步互斥工具(如P操作、V操作)来对共享空间进行读写控制。
②消息传递:若通信进程不存在共享空间,则可通过OS提供的消息传递方法实现通信。分为直接通信方式和间接通信方式(有中间实体,成为“信箱”)。
③管道通信:其消息传递的一种特殊方式。所谓“管道”,是指用于连接读进程和写进程以实现二者通信的共享文件,又名pipe文件。管道机制需具备:互斥、同步、确定对方存在三方面能力。