操作系统之 进程

进程

进程是指运行中的程序,是系统进行资源分配和调用的单位,当这个程序进入系统内存中时即为线程。
每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销(及上下文切换),一个进程包含1--n个线程。
进程是资源分配的最小单位。

进程状态:
进程在执行的过程中会改变状态,进程状态有:
新的(new):进程正在创建
运行(running):指令正在执行
等待(waiting):进程等待发生某个时间(如I/O完成等等)
就绪(ready):进程等待分配处理器
终止(terminated):进程执行完成
状态转移图如下:
操作系统之 进程

进程的特点:

独立性:进程可以独立拥有资源,每一个进程都有自己独立的地址空间。
动态性:进程是动态的,在进程中有时间的概念,进程具有自己的生命周期和各种不同的状态(如上图)。
并发性:多个进程可以在单个处理器上并发执行,互不影响。

进程的创建:

UNIX系统中调用fork()函数进行父进程对子进程创建,让子进程继承了父进程的地址空间。
windows系统中采用CreateProcess()来创建,创建时需要将一个特定的程序加载到子进程的地址空间,且需要传递大量的参数。

以unix系统为例,进程在执行的过程中可以创建多个新的进程,前者称为父进程,后者称为子进程,每个新的进程也还可以创建其他的进程,从而形成一个进程树。每个进程都有一个唯一的进程标识符pid,可作为索引,以便访问内核中的进程的各种属性。对于子进程,系统调用fork()函数会返回0,而父进程返回的是子进程的pid。

进程的销毁:

当进程执行完最后一条语句且系统调用exit()函数请求系统删除自身时,进程终止。此时进程可以返回状态值到父进程,所有进程的资源都将被释放。
当一个进程终止时,系统会释放其资源,但是它位于进程表(包含了进程的退出状态)中的条目还是存在的,直到父进程调用了wait()。当进程已经终止,但是父进程并没有调用wait()时,该进程便称为僵尸进程。所有进程都会经历这种状态,一般只是短时间存在。
如果父进程没有调用wait()函数就终止了,那么子进程就会变为孤儿进程。此时的处理方法是:将init进程(UNIX中进程树的根进程)作为孤儿进程的父进程,定期调用wait(),以便手机任何孤儿进程的退出状态以及释放相应的资源。

进程间通信:
需要进程通信的理由有:
信息共享:可使得多个用户对同样的信息进行访问。
计算加速、模块化、方便.........
进程间通信有两种基本模型:共享内存和消息传递,如下图:操作系统之 进程

共享内存快与消息传递,因为消息传递的实现需要采用系统调用。而内存共享只在建立共享区时需要系统调用,一旦建立后所有访问便为内存访问,无需借助内核。

管道允许两个进程进行通信,管道分为普通管道和命名管道。
普通管道允许进程间按照生产者-消费者模式进行通信,生产者向管道一端写,消费者从另一端读,因此普通管道是单向的,也被称为匿名管道。
命名管道可以允许不相关的进程之间的通信。