[TOC]
进程管理和通信
主要内容
进程概念
线程概念
进程/线程控制
同步和互斥
临界资源和临界区
信号量和P,V操作
经典同步问题
进程通信
重点
进程概念和编程应用
线程概念和编程应用
同步的概念和P-V操作原理
同步的编程应用
进程通信编程
课程知识小结
4.1进程概念
定义:进程是程序在某个数据集合上的一次运行活动
数据集合:软/硬件环境,多个进程共存/共享的环境
特征:
1.动态性:进程是程序的一次执行过程,动态产生/消亡
2.并发性:进程可以同其他进程一起向前推进
3.异步性:进程按各自速度向前推进
4.独立性:进程是系统分配资源和调度CPU的单位
进程与程序的区别:
1.动态与静态
进程是动态的:程序的一次执行过程
程序是静态的:一组指令的有序集合
2.暂存与长存
进程是暂存的:在内存驻留
程序是长存的:在介质上长期保存
3.程序和进程的对应关系
一个程序可能有多个进程
进程类型:
1.按使用资源的权限
系统进程:指系统内核相关的进程。
用户进程:运行于用户态的进程
2.按对CPU的依赖性
偏CPU进程:计算型进程
偏I/O进程:侧重于I/O的进程
3.其他……
4.2进程的状态
![](https://img-blog.csdnimg.cn/img_convert/db89d8b40963d64042afdd5fab40b06c.png)
状态的变迁:
没有其他转换过程了
其他的扩展状态变迁:
Linux进程的状态
变迁过程:
4.3进程控制块
Linux中的PCB:
![](https://img-blog.csdnimg.cn/img_convert/fa353117f9152b37c3715d2fb397147b.png)
每个进程有唯一编号:PID
除init进程外,每个进程都可用kill命令杀死
新进程ID达到系统最大值时,使用最小未用的PID
进程的切换
![](https://img-blog.csdnimg.cn/img_convert/09c44f0763866782c90903bd7b2beb6d.png)
例子:
4.4进程控制
概念:在进程生存全期间,对其全部行为的控制
四个典型控制:
创建进程
撤消进程
阻塞进程
唤醒进程
进程创建
过程
进程撤销
进程阻塞
进程唤醒
进程控制原语
由若干指令构成的具有特定功能的函数
具有原子性,其操作不可分割
进程控制原语
创建原语
撤消原语
阻塞原语
唤醒原语
4.5Windows进程控制
最底层的是CreateProcess
![](https://img-blog.csdnimg.cn/img_convert/b1ba8ebb2c95d7928a64605e394f1f5b.png)
结束进程
![](https://img-blog.csdnimg.cn/img_convert/99e0ad3da0bbe74da8d9835bbd8e0e00.png)
第二个方式是通过任务管理器强制结束
4.5Linux进程控制
创建进程——fork()
函数定义:pid_t fork(void)
创建进程:例: pid_t pid = fork( ) ;
父进程和子进程
子进程:新建的进程
父进程:fork( )的调用者
子进程是父进程的复制。
父进程和子进程并发运行
例:
【发现输出了两个字符串】
![](https://img-blog.csdnimg.cn/img_convert/213e93ad278adf92aecff5b0f29f36c6.png)
【在子进程中,pid为0,父进程pid大于0(pid就为子进程的ID),fork函数返回子进程的ID。但父子进程并发,谁先运行不确定】
![](https://img-blog.csdnimg.cn/img_convert/979adb591d52a8318fbb230f80ba9f9e.png)
【子进程从父进程调用fork()函数的下一行开始执行】
子进程由fork( )创建后,通常处于就绪状态
init进程:
在Linux系统初启时,生成init进程(1号进程)
其他进程由当前进程通过系统调用fork( )建立
fork函数的实现——do_fork函数
UNIX——创建和执行
fork函数:复制当前进程创建子进程
exec函数:读取可执行文件并载入进程空间执行
Linux版本——COW,Copy On Write,写时复制
父进程的资源被设置为只读,当父进程或子进程试图修改某些内容时,内核才在修改前将该部分进行拷贝——写时复制
fork( ) 的实际开销只是复制父进程的页表以及给子进程创建唯一的PCB
进程执行与父进程不同的功能
【exec调用失败返回-1,继续在克隆来的地址空间中从调用点向下执行】
阻塞——wait()
![](https://img-blog.csdnimg.cn/img_convert/19b11850fd8d6c23036cfd06cc49b608.png)
结束进程——exit()
休眠——sleep()
进程层次关系
进程组/Group
进程组是一组相关进程的集合。
每个进程都属于某个进程组/PGID
子进程默认继承父进程PGID
进程组有时称为作业/JOB
getpgid( ) /setpgid( )
4.6线程
例子:编写程序同时画圆画方
使用线程(Thread)
概念
![](https://img-blog.csdnimg.cn/img_convert/7c73aeb7456c46ac3914ed2b5aa541c0.png)
线程状态变迁
![](https://img-blog.csdnimg.cn/img_convert/748cc5d360c57b5faad6622a249e58ba.png)
创建线程
把画圆函数DrawCircle和画方函数DrawRect
分别作为参数传给CreateThread函数的第3个参数
单线程程序:整个进程只有一个线程。Windows程序缺省创建一个线程(主线程,main线程)
多线程程序:整个进程至少有2个线程。主线程和至少1个用户线程
线程应用场景
1.多个功能需要并发的地方
2.需要改善窗口交互性的地方(文件拷贝、用户登录等)
3.需要改善程序结构的地方
4.多核CPU上的应用,充分发挥多核性能
4.7进程相互制约关系
进程的互斥关系
多个进程由于共享具有独占性的资源,必须协调各进程对资源的存取顺序:确保没有任何两个或以上的进程同时进行资源存取
进程的同步关系
若干合作进程为了共同完成一个任务,需要相互协调运行步伐:一个进程A开始某个操作之前要求另一个进程B必须已经完成另一个操作,否则进程A只能等待
例子:
司机和售票员
(1)司机起步前售票员先关门,否则司机等待;
(2)售票员开门前司机先停车,否则售票员等待
另一种解释:
合作进程中某些操作之间需要满足某种先后关系或某个操作能否进行需要某个前提条件满足,否则只能等待
互斥关系属于特殊的同步关系
下面介绍临界资源和临界区
临界资源和临界区
![](https://img-blog.csdnimg.cn/img_convert/ec9b84eb968dd0d29229f2b3b1005bbf.png)
【同时运行时,输出的i(为全局变量)可能为不正确的结果,为了避免这种情况,我们设定一个区域,使其不能同时访问】
临界资源:一次只允许一个进程独占访问(使用)的资源(例如例子中的共享变量i)
临界区:进程中访问临界资源的程序段
临界资源的访问具有排他性;
并发进程不能同时进入“临界区”;
临界区设置应该适中
设置临界区访问机制四个原则**(常考)**
1.忙则等待:临界区忙时,其他进程在临界区外等待
2.空闲让进:无进程在临界区时,可进入临界区
3.有限等待:进程进入临界区的请求应该在有限时间得到满足(不能一直等待)
4.让权等待:等待进程放弃CPU(进程在等待时,不应该一直占据CPU,而将其给其他进程使用)
4.8同步机制
锁机制
基本原理:设置一个标志S——(1:可用;0:不可用)
上锁操作:进入临界区前检查S——
若不可用,等待;可用,访问之,并改变S为0
开锁操作:离开时,修改S为1
上锁
开锁
锁机制访问临界区
目标:确保临界区中任何时候最多只有1个进程运行于其中
步骤:
1. 初始化锁的状态S = 1 ( 可用)
2. 进入临界区之前执行上锁Lock(s)操作;
3. 离开临界区之后执行开锁unLock(s)操作。
锁机制是否满足四个设计原则?
信号灯和P-V操作
信号灯基本思想:进程在运行过程受信号灯控制,并能改变信号灯
进程受控制:进程因信号灯的状态被阻塞或被唤醒。
改变信号灯:信号灯的状态可以被进程改变
信号灯数据结构
信号灯定义为一个二元矢量(S, q)。
S:整数,初值非负(S又称信号量)
q:队列(进程PCB集合),初值为空集
两个操作:
P(通过)操作(函数或过程,P(S,q))
V(释放)操作(函数或过程,V(S,q))
P操作
V操作
解决互斥问题
进程互斥:实质是实现对临界区的互斥访问
1个临界资源:最多允许1个进程同时处于临界区
M个临界资源:允许最多M个进程同时处于临界区
应用过程
进入临界区之前先执行P操作;(可能阻塞当前进程)
离开临界区之后再执行V操作;(可能唤醒另外的某个进程)
S的初值设置要合理(S初值为临界资源的数量)
![](https://img-blog.csdnimg.cn/img_convert/6f1b0feec3757ee7d5e854753da6285d.png)
【Pa先运行,进行Pa中的P操作,mutex减1,变为0,可以继续运行;假设随后Pb运行其中的P操作,mutex减一变为-1,小于0,不能运行,被阻塞,同理Pc。】
![](https://img-blog.csdnimg.cn/img_convert/0ab9d9a49bd32431e3f3fa4f3c89700d.png)
【之后,Pa访问好后,执行V操作,mutex加一后变为-1,此时mutex小于零,根据V操作会唤醒一个进程,假设唤醒Pb,继续运行Pb的V操作,同理Pc。当Pc的V操作将mutex从0加到1时,不再唤醒新进程】
假设我们将mutex设置为其他的数呢?
信号量S能明确地表示“运行条件”:临界资源的数量(同时访问临界区的进程数)
解决同步问题
实现进程同步的例子:司机和售票员
【这里的信号量有两个S1,S2】
经典同步例子
(1)进程流图
(2)共享缓冲区问题
假设缓冲区有5个空位
【缓冲区的值就是信号量的值】
同步要求 (输出数据不重复不遗漏)
仅当Buffer有数据时,OUTPUT才能输出,否则必须等待。
仅当Buffer有空位时, INPUT才能输入,否则必须等待
规则:
不能向满的缓冲区存;不能从空的缓冲区取
![](https://img-blog.csdnimg.cn/img_convert/634ec8be8c25f0e866a9fbf8803e6ea6.png)
【多个缓冲区位置时,space值就设置为那个数目即可】
(3)生产者和消费者问题
同之前缓冲区问题类似,但是多一个条件:每个时刻生产者或消费者只能有1个存或取缓冲区
【多定义了一个mutex,实现生产者和消费者之间的互斥】
(4)读者和编者问题
![](https://img-blog.csdnimg.cn/img_convert/87c5cff4b7540e0712df60187e90bfe0.png)
【当ReadCount为1时,有一个读者来读,不能编辑,但为2时,是允许来读的;当减到0时,才允许编辑】
4.10Linux同步机制
Linux的同步(MOOC才有,ppt没有)
阻塞——wait()
退出——exit()
![](https://img-blog.csdnimg.cn/img_convert/f5a6fb64c6a716eb2f15c87749e716ec.png)
休眠——sleep()
若对于文件共享时,共享的是其指针
4.11进程通信(IPC/Linux)(只考Linux信号)
信号
信号的产生
Linux定义了64种信号
signal():自定义信号
kill():发送信号
简答
1.进程具有异步性,是进程的优点还是缺点呢
是优点。异步可以提高系统运行效率,例如当某进程在加载资源时,可以异步执行,将系统资源让给其他进程。同时,异步运行也不影响进程的同步性,当需要同步执行某些进程时,可以使用进程的消息管理机制控制进程的运行
2.为何没有“阻塞到运行”或“就绪到阻塞”这样的状态迁移
个人的理解是,就绪态的操作相当于一个队列等待。想要运行,在一定的优先级条件下首先要进入队列排队,而排队中的进程直到进入运行状态才能进行进入阻塞态等操作。
如果有“阻塞到运行”或“就绪到阻塞”的操作,实质上就打破了常规的流程,需要专门写一段代码处理这两种情况,降低系统稳定性
3.进程控制块中“内部进程通信信息”这一类成员变量的作用是什么
不同进程间的交互,数据通信,互斥与同步
4.如何理解fork()函数的返回值有2个取值
fork()会返回pid参数,用于判断是子进程还是父进程。pid=0,是子进程;pid>0,是父进程,且值为子进程ID;pid=-1,出错
5.画圆和画方两个过程是完全同步的吗
不会完全同步,因为首先创建的线程会先执行。要提高同步性,应首先创建好两个进程,然后采用时钟触发的方式同时执行
6.WINDOWS中,在程序启动exe程序创建相应进程的方法
1、system()
2、WinExec()
3、SheelExcute()
4、CreateProcess()
CreateProcess()是最底层的创建进程方法,创建进程内核对象,创建虚拟地址空间,装载exe、dll代码和数据到地址空间,创建主线程和线程内核对象,启动主线程并进入main函数。前三种函数是对CreateProcess()的封装简化,system()最简单,直接传入exe文件目录就可以直接开启进程
7.临界区的设置大些好还是小些好?各有什么缺点
应在满足访问控制的条件下尽可能小。太大会造成不必要的阻塞,太小满足不了访问控制的条件
8.Linux信号机制与中断机制有什么异同
信号和中断的相似点:
都采用了异步通信的方式,同步就是排队,信息一个接一个的处理,异步就是插队;
都是暂停当前的, 去执行对应的handle程序;
都是处理完返回原来位置;
对于信号和中断, 都是可以屏蔽的。
信号与中断的区别:
中断有优先级, 信号没有;
信号处理程序在用户态下运行的, 中断程序在核心态下运行的;
中断响应是及时的, 当信号响应一般有延迟
MOOC单元作业
1.进程有哪4个特征
动态性:进程是程序的一次执行过程,动态产生和消亡;
并发性:进程同其他进程一起向前推进;
异步性:进程按各自速度向前推进;
独立性:进程是系统分配资源和调度CPU的单位。
2 进程有哪3个基本状态,它们之间如何迁移
运行状态:进程已占有CPU,在CPU上运行;
就绪状态:举报运行条件但由于无CPU,暂时不能运行;
阻塞状态:因为等待某项服务完成或信号不能运行的状态。
新建的进程会进入就绪状态,根据进程调度进入运行状态,若有退出信号则进入终止状态,若需等待I/O或事件则进入阻塞状态,若时间片已到则进入就绪状态,阻塞状态的进程等到I/O信号或事件信号后进入就绪状态
3.什么是进程控制,有哪4个典型的进程控制行为
进程控制是指在进程生成全周期内,对其全部行为的控制。
四个典型控制行为包括:
创建进程、阻塞进程、撤销进程和唤醒进程
4.什么是原语,有何特点
原语是由若干指令构成的具有特定功能的函数。具有原子性,其操作不可分割
5.试述fork()函数的作用和特点
fork()是一个系统调用,用于创建进程。一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。新进程是当前进程的子进程,子进程是父进程的复制,子进程和父进程并发运行。
fork()会返回pid参数,用于判断是子进程还是父进程。pid=0,是子进程;pid>0,是父进程,且值为子进程ID;pid=-1,出错。
6.试述线程的概念(Thread)和特点
线程是可由CPU直接运行的实体;
一个进程可以创建多个线程;
多个线程共享CPU可以实现并发运行
7.试述线程有哪些典型应用场合
1、程序需要并发运行多个功能;
2、需要改善窗口交互性的地方,例如用户输入、文件操作、网络操作、搜索等;
3、需要改善程序结构的地方,后台程序;
4、多核CPU上的应用,重复发挥多核性能。
8.何为临界资源,何为临界区
临界资源是指一次只允许一个进程独占访问的资源。临界区是指进程中访问临界资源的程序段。
9.试述设计临界资源或临界区访问机制的四个原则是什么
忙则等待、空闲让进、有限等待、让权等待
10.临界区访问机制为什么要实现让权等待原则?锁机制为什么没有满足该原则
让权等待可以让其它进程有机会得到CPU。
锁机制的lock()函数一直在测试S的值,没有停下,一直在占用CPU
11.什么是进程的互斥,什么是进程的同步?各举一个例子说明
进程的互斥是指多个进程由于共享了独占性资源,必须协调各进程对资源的存取顺序,确保没有两个或两个以上的进程同时进行存取操作。例如临界资源的使用。
进程的同步是指若干进程为了完成一个共同的任务,需要相互协调运行步伐,一个进程开始某个操作之前必须要求另一个进程已经完成某个操作,否则前面的进程只能等待。例如司机和售票员之间的操作
12.P-V操作的作用是什么?P操作和V操作各自的原理是什么?
P-V操作为了实现信号灯进程同步机制。信号灯包含S和q两个属性,S表示信号量,q表示PCB队列。进程可以通过P-V操作改变信号灯的状态,同时进程的状态也受信号灯状态的约束。
P操作将S减1;若差大于等于0,该进程继续;若差小于0,则进程阻塞并加入队列q。
V操作将S加1;若和大于0,进程继续;若和小于等于0,该进程继续同时从q唤醒一个进程
13.试述P-V操作解决互斥问题的思路是什么
1、设定合适的S初值;
2、进入临界区前执行P操作;
3、离开临界区之后执行V操作
14.试述P-V操作解决同步问题的思路是什么
1、定义有意义的信号量S,并设置合适的初值;
2、暂停进程时在关键操作前执行P操作;
3、继续进程时在关键操作后执行V操作。
15.试分析“司机vs售票员”同步问题中,哪些操作是关键操作,哪些不是?为什么
关键操作有关门、起步和停车、开门。行驶和售票不是关键操作。关键操作涉及到与其他进程的交互,非关键操作不涉及其他进程,只需满足进程内的逻辑
16.试分析“生产者与消费者”问题中,P-V操作是如何阻止生产者生产速度过快的,又是如何阻止消费者消费速度过快的?又是如何及时唤醒生产者去尽快生产的,又是如何及时唤醒消费者去尽快消费的?
添加规则,不能向满缓存区存产品,不能从空缓存区取产品,当缓存区已满,生产者处于阻塞态,只有消费者可以运行,当缓存区已空,消费者处于阻塞态,只有生产者可以运行
17.试述Linux中wait函数和exit函数的作用和它们之间的联系
wait(int status)可以阻塞自己,当有子进程结束,wait收集该子进程信息并销毁该子进程后返回。
exit(int status)可以终止进程,利用status传递进程结束时的状态,然后变为僵尸状态,保留部分PCB信息供wait收集
18.试述Windows管道通信或Linux信号机制的原理(或如何应用该机制)
管道是一种用于在进程间共享数据的机制,其实质是一段共享内存。Windows系统为这段共享的内存设计采用数据流I/0的方式来访问。由一个进程读、另一个进程写,类似于一个管道两端,因此这种进程间的通信方式称作“管道”。
管道分为匿名管道和命名管道:
匿名管道只能在父子进程间进行通信,不能在网络间通信,而且数据传输是单向的,只能一端写,另一端读,为实现双向通信,需建立两个匿名管道;
命令管道可以在任意进程间通信,通信是双向的,任意一端都可读可写,但是在同一时间只能有一端读、一端写。
匿名管道使用方法:
1、创建一个安全属性描述符,设置句柄可继承
2、创建两个管道,父读子写和子读父写
3、重定向输出,将子进程的读写重定向
4、创建子进程
5、读写数据给子进程