本章还是从整体上讲解了进程,包括 4 个方面: 1)进程概念 2)进程的特性(进程调度、创建、终止) 3)进程间通信 4)客户机-服务器通信
多个程序要并发执行,才有了进程的概念。
进程时执行的程序,有生命周期。而程序只是被动(passive)实体,是死的。进程是活动(active)实体。
进程的内容包括:程序代码、数据段、堆、栈。
进程有 5 种状态:
新的:进程正在创建运行:指令正在运行等待:进程等待事件发生就绪:等待分配处理器终止:已经完成执行 每一个进程都有一个进程控制块(Process Control Block, PCB)。 进程控制块包含许多与特定进程相关的信息。进程状态(5种状态)程序计数器(将要执行的下一个指令的地址)CPU寄存器(寄存器的值,为保存现场)CPU调度信息(优先级、调度队列的指针、……)内存管理信息记账信息(CPU时间、实际使用时间……)IO状态信息多道程序设计的目标就是,无论何时都有进程运行,从而最大化CPU利用率。 分时系统就是在进程之间快速地切换CPU,以便用户在运行时能与其交互。
为了满足上述要求,就需要一个**进程调度器(process scheduler)**选择一个可用的进程到CPU执行。
那就有了调度队列和调度程序。 调度队列就是把一些状态相同的进程保存在队列中,等待被调度。 调度队列中那么多进程,选哪个呢?调度程序就是在调度队列中选择进程的程序。
进程进入系统时,会被加到作业队列,这个队列包括系统内的所有进程。
所有驻留在内存中、就绪的、等待运行的进程保存在就绪队列。
等待特定IO设备的进程列表,称为设备队列。比如多个进程向一个共享进程发送IO请求,那么它们就同在一个设备队列中。
进程调度通常用队列图来表示。
从队列中选择合适的程序,使得系统最有效率。 两种: (1)长期调度程序或作业调度程序:从缓冲池中选择进程,加到内存,以便执行。 (2)短期调度程序或CPU调度程序:从准备执行的进程中选择进程,并分配CPU。
中断导致CPU从执行当前任务改变到执行内核任务。
中断发生时,系统需要保存当前运行在CPU上的进程的上下文,以便在处理后能够恢复上下文,即先挂起程序,再恢复程序。
上下文切换的时间与硬件支持密切相关。
上一节讲了进程的调度,这一节讲进程的另外两个状态:创建和终止。
动态创建进程。 每个进程有唯一的进程标识符(precess identifier,pid)
结合UNIX中的例子来表达进程的创建
#include <sys/types.h> #include <stdio.h> #include <unistd.h> int main() { pid_t pid; pid = fork(); //创建子进程 if (pid < 0){ //创建失败 fprintf(strerr, "Fork Failed"); return 1; } else if (pid == 0){ //子进程 execlp("/bin/ls","ls",NULL); //使用新程序取代进程的内存空间。 } else{ //父进程 wait(NULL); //等待回收子进程 printf("Child Comlete"); } return 0; }当进程完成执行最后语句并通过系统调用 exit() 请求操作系统删除自身,进程终止。 其他情况也会出现进程终止,一般是父进程终止子进程。
父进程可以调用 wait() 来等待子进程的终止。
pid_t pid; int status; pid = wait(&status);僵尸进程:当进程已经终止,父进程尚未调用 wait() ,这样的进程称为僵尸进程。所有的进程终止都会过渡到这个状态,一般僵尸状态只是短暂存在。
孤儿进程:父进程没有调用 wait() 就终止,以致于子进程称为孤儿进程。UNIX和Linux中将init 进程作为孤儿进程的父进程,init 进程定期调用 wait() ,以便收集任何孤儿进程的退出状态。
进程间通信有两种基本模型:共享内存和消息队列。
一片共享内存区域驻留在创建共享内存段的进程地址空间内,其他希望使用这个共享内存段进行通信的进程应将其附加到自己的地址空间。 这样,每个进程都是访问自己的地址空间,但是这个地址空间是公共的。
消息传递提供一种机制,以便允许进程不必通过共享地址空间来实现通信和同步。
消息传递工具提供至少两种操作:
send(message); receive(message);POSIX共享内存 Mach系统的消息传递 Windows
套接字(socket)、远程程序调试(RPC)、管道
socket 的原意是“插座”,在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式。通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据。
套接字定义通信的端点,一对应用程序之间的连接由一对套接字组成,通信的两端各有一个套接字。
RPC是另一种形式的分布式通信。
管道提供了一个相对简单的进程间互相通信。 普通管道允许父进程和子进程之间的通信,而命名管道允许不相关进程之间的通信。
本章还是从整体上讲了进程相关的一些知识。 而在后续章节中,会把本章再继续展开,深入细致的分析进程相关的知识。
