1、什么是进程同步
知识点回顾:进程具有异步性的特征。异步性是指,各并发执行的进程以各自独立的、不可预知的速度向前推进;
前面举过一个例子,老渣并发执行两个约会任务:
一号约会进程的指令1:老渣陪我吃饭;
一号约会进程的指令2:老渣把心给我;
二号约会进程的指令1:老渣把心给我;
二号约会进程的指令2:老渣陪我吃饭;
每一个约会进程都有老渣需要执行的指令,由于并发执行的进程有异步性,所以这些指令的推进顺序是不可预知的;
所以老渣可能有以下约会方式:
8点~9点:一号;
9点~10点:一号;
10点~11点:二号;
11点~12点:二号;
上述约会方式首先执行一号的指令一,接着执行一号的指令二,也就是老渣把心给一号;接下来如果调度二号的约会进程,二号的指令一是老渣把心给二号,但此时老渣的心已经给一号,所以二号的指令没办法执行;
老渣也有可能是以下约会方式:
8点~9点:一号;
9点~10点:二号;
10点~11点:一号;
11点~12点:二号;
由于异步性导致并发进程的推进顺序是不可预知的;如果女一号只想做老渣的初恋,女二号只香交一个有恋爱经验的渣男;那么老渣在并发执行这两个约会进程的时候,就必须保证“一号的指令2”一定要在“二号的指令1”之前执行;
在这种情况下,我们必须保障并发的两个进程之间的推进顺序是可预知的;进程的异步性有时候是我们必须解决的事情,让进程按我们想要的顺序来依次推进;
基于上述分析,操作系统需要提供“进程同步机制”来实现上述需求。
再看另一个例子:进程通信——管道通信:
管道通信,写进程需要往管道中写数据,当管道中数据写满之后,读进程才能执行读数据的操作;
写进程和读进程并发地执行,由于并发必然导致异步性,因此“写数据”和“读数据”两个操作执行的先后顺序是不确定的。而实际应用中,又必须按照“写数据->读数据”的顺序来执行的;
为了解决上述的进程异步问题,就提出了“进程同步”;
同步亦称直接制约关系,它是指为完成某种任务而建立的两个或多个进程,这些进程因为需要在某些位置上协调它们的工作次序而产生的制约关系。进程间的直接制约关系就是源于它们之间的相互合作;
进程同步亦称直接制约关系,它是指为完成某些任务而建立的两个或多个进程,这些进程因为需要在某些位置协调它们的工作次序而产生的制约关系。进程间的直接制约关系就是源于它们之间的相互合作;
2、什么是进程互斥
进程的“并发”需要“共享”的支持,各个并发执行的过程不可避免的需要共享一些系统资源(比如内存,又比如打印机、摄像头这些I/O设备);
两种资源共享方式:
- 互斥共享:系统中的某些资源,虽然可以提供给多个进程使用,但一个时间段只允许一个进程访问该资源;
- 同时共享:系统中的某些资源,允许一个时间段内多个进程“同时”对它们进行访问;
我们把一个时间段内只允许一个进程使用的资源称为临界资源。许多物理设备(比如摄像头、打印机)都属于临界资源。此外还有许多变量、数据、内存缓冲区等都属于临界资源;
对临界资源的访问,必须互斥地进行。互斥,亦称为间接制约关系。进程互斥指当一个进程访问某临界资源时,另一个想要访问该临界资源的进程必须等待。当前访问临界资源的进程访问结束,释放该资源之后,另一个进程才能去访问临界资源;
对临界资源的互斥访问,可以在逻辑上分为如下四个部分:
do {
entry section; // 进入区;
critical section; // 临界区;
exit section; // 退出区;
remainder section; // 剩余区;
}
- 进入区:负责检查是否可进入临界区,若可进入,则应设置正在访问临界资源的标志(可理解为“上锁”),以阻止其它进程同时进入临界区;
- 临界区:访问临界资源的那段代码;
- 退出区:负责解除正在访问临界资源的标志(可理解为“解锁”);
- 剩余区:做其它操作;
注意:
- 临界区是进程中访问临界资源的代码段;
- 进入区和退出区是负责实现互斥的代码段;
- 临界区也可称为“临界段”;
为了实现对临界资源的互斥访问,同时保证系统整体性能,需要遵循以下原则:
- 空闲让进:临界区空闲时,可以允许一个请求进入临界区的进程立即进入临界区;
- 忙则等待:当已有进程进入临界区时,其它试图进入临界区的进程必须等待;
- 有限等待:对请求访问的进程,应保证能在有限时间内进入临界区(保证不会饥饿);
- 让权等待:当进程不能进入临界区时,应立即释放处理机,防止进程忙等待;