揭开进程的概念、状态、通信的迷雾。看完瞬间豁然开朗
预备知识
前驱图
程序顺序执行的特征
顺序性顺序执行
封闭性独占资源
可再现性只要程序执行环境和初始条件相同,重复执行时结果都相同
程序并发执行的特征
间断性
失去封闭性
不可再现性因为程序并发执行时,是多个程序共享系统中的各种资源,因而这些资源的状态是由多个程序来改变,致使程序的运行失去了封闭性。而程序一旦失去了封闭性也会导致其再失去可再现性。执行结果与并发程序的执行速度相关
进程的概念
非正式地说,进程是执行的程序。进程不只是程序代码,程序代码又称为文本段或代码段。进程还包括当前活动(程序计数器的值、处理器寄存器的内容)。通常还包括进程堆栈(临时数据)、数据段(全部变量)。还可能包括堆(进程运行时动态分配的内存)。
进程的特征
动态性进程有生命周期,最基本特征。
并发性可并发执行;引入进程的目的是为了使其进程实体能和其他进程实体并发执行
独立性进程实体是一个能独立运行、独立获得资源和独立接受调度的基本单位
制约性进程间对资源的争用而相互制约
异步性进程按照各自独立的、不可预知的速度向前推进
结构特征进程=程序+数据+PCB
进程和程序的比较
进程是程序的一次运行过程,是一个动态实体,而程序是一个指令的集合,是静态实体。进程具有生命周期,具有创建、执行和撤销的过程,而程序一旦创建,可以永远存在 。进程实体由程序段、数据段及进程控制块组成。进程与程序之间不存在一一对应的关系,不同的进程可以对应相同的程序,一个进程中还可以同时调用多个程序。进程实体是一个能独立运行的基本单位,可独立获得资源和独立调度;而程序不能作为独立的单位参加运行。进程可按异步方式运行,程序不是运行实体,所以不可以异步执行。
进程的状态
就绪、运行、等待是三个基本状态。
提交状态
后备状态
就绪状态
运行状态
等待状态
结束状态
进程的挂起/解挂
设置挂起/解挂的原因用户需要:中间结果与预期不符。操作系统需要:系统某些功能故障。系统负荷过重 。父进程请求:修改或协调子进程 。对换的需要。
进程控制块(PCB)
PCB 是用以记录与进程相关信息的主存区,是进程存在的唯一标志
具有相同状态进程的 PCB 分别通过 PCB 中的链接字链接成一个队列。
C/C++Linux 服务器开发高级架构师学习文档电子书籍 点击 linux服务器学习资料 获取,内容知识点包括 Linux,Nginx,ZeroMQ,MySQL,Redis,线程池,MongoDB,ZK,Linux 内核,CDN,P2P,epoll,Docker,TCP/IP,协程,DPDK 等等。视频免费学习链接:C/C++Linux服务器开发高级架构师/Linux后台架构师-学习视频
索引方式
系统根据所有进程状态的不同,建立几张索引表,并把索引表的首地址记录在内存的专用单元中。
Linux PCB 的例子
进程切换/上下文切换
切换 CPU 到另一个进程需要保存当前进程状态和恢复另一个进程的状态,内核会将旧进程状态保存在 PCB 中,并加载调度新的进程。上下文切换的时间是纯粹的开销。有的处理器提供多个寄存器组,上下文切换只需简单改变当前寄存器组的指针(如果活动进程数量超过寄存器组的组数,系统仍要在寄存器和内存之间复制数据)。
进程的创建
进程图
进程图(有向树)与前趋图(有向无环图)的 2 个区别:1、表示的含义不同;2、执行时处理不同:可并发执行
进程创建原语 Creat()
申请空白 PCB
为新进程分配资源
初始化 PCB
新进程插入就绪队列
父进程创建子进程
当一个进程创建子进程时,子进程会需要一定的资源。子进程可以直接从操作系统那获得资源,也可以只从父进程那里获得资源子集。父进程可能要在子进程之间分配资源或共享资源。限制父进程只能使用父进程的资源,可以防止创建过多进程,导致系统超载。
父与子进程的执行可能父进程和子进程并发执行父进程等待,直到某个或某些子进程执行完毕
新进程的地址空间的情况子进程完全复制父进程,拥有同样的程序和数据子进程加载另一个新程序
Unix 举例
fork()通过系统调用 fork()创建新进程,新进程的地址空间复制了原来进程的地址空间。子进程和父进程都继续执行 fork()调用后的指令。但对于父进程,fork()返回子进程的进程标识。对于子进程,fork()返回 0。
exec()在调用 fork()后,可以有个进程调用 exec(),用新程序取代进程的地址空间(加载二进制文件到内存),并开始执行。
wait()父进程创建子进程后,如果无事可做,就调用 wait()把自己移除就绪队列,直到子进程结束,wait()返回(可以获得子进程的标识符、退出状态等信息),父进程从 wait()的下一条指令开始继续执行。
进程的终止
级联终止
如果一个进程终止,那么它的所有子进程也相应终止,称为级联终止。
僵尸进程
当一个进程终止时,操作系统会释放它的资源,但是位与进程表中的条目还在,直到它的父进程调用 wait()。因为进程表中包含了进程的退出状态,当进程已经终止,但它的父进程还没有调用 wait()时,这样的进程称为僵尸进程。一旦父进程调用 wait(),僵尸进程的进程标识符和进程表中的条目就会被释放。
孤儿进程
如果父进程没有调用 wait()就终止,它的子进程称为孤儿进程。Linux 和 Unix 的做法是,将 init 进程作为孤儿进程的父进程。init 进程定期调用 wait(),以便收集孤儿进程的退出状态,释放孤儿进程的标识符和进程表条目。
进程间通信
操作系统内的并发执行程序可以是独立的,也可以是协作的,若是协作的,那么就需要有一种进程间通信(IPC)的机制。
生产者-消费者问题
进程通信的类型
消息传递对于较小数量的数据交换很有用,因为无需避免冲突。对于分布式系统,消息传递也比共享内存更易实现。共享内存可能快于消息传递,因为消息传递的实现经常采用系统调用,需要消耗更多时间使内核介入。共享内存仅在建立共享内存区域使需要系统调用,建立后所有访问都可作为常规内存访问,无需借助内核。
共享存储器
消息传递
由操作系统提供机制,利用系统提供的通信原语,以消息或报文为单位进行信息交换。
命名
间接通信
同步
缓存
管道通信
评论