操作系统-----------进程的互斥和进程的同步超详解!!!

一、进程的互斥:

   1.定义

        比如一台计算机连着一台打印机,而且现在有多个打印进程,都想要进行打印,但是打印机不可能进行多个打印进程(如果这样做就乱套了),所以这些打印进程之间就存在着一种互斥关系,这时候 打印机可以被看成一种临界资源,在某个时刻内只能有一个进程占用这个临界资源,等这个进程结束,打印机资源才被释放,其他的进程才能使用这个临界资源

   2.实现进程互斥的方法

        因为打印机属于临界资源,所以可以用互斥信号量mutex表示,而且打印机只有一台,所以可以令mutex=1。

/*信号量机制实现互斥*/
semaphore mutex=1//定义并初始化信号量

P1(){
	...
	P(mutex);     //使用临界资源前需要加锁 
	临界代码段..  
	V(mutex);     //使用临界资源后需要解锁 
	... 
}

P2(){
	...
	P(mutex);     //使用临界资源前需要加锁 
	临界代码段..  
	V(mutex);     //使用临界资源后需要解锁 
	... 
}

  注:P,V操作就是 wait 和 signal 操作。wait 和 signal 是一对原语,可以把原语理解成我们自己写的函数,函数名为 wait 

和 signal ,括号里面的信号量其实就是函数调用时传入的一个参数。

wait和signal函数原型:点击这里!!!

           这里面有一点要注意,假设现在正在进行P1进程的P(mutex); 执行完这一行说不定就切换进程就去执行其他进程去了,原因可能是进程调度的方式不同,可能该进程的时间片用完了或者他的原因(原因有多种,这里只是说的一种可能情况)

二、进程的同步

    1.定义

                 要让各并发按照要求有序的推进。

P1(){               
	代码1;
	代码2;
	代码3; 
} 
P2(){               
	代码4;
	代码5;
	代码6; 
} 

比如上面的P1,P2进程并发执行,由于存在异步性,因此二者交替推进的次序是不确定的(可能会发生中途切换进程的情况)        

         但有时候我们会要求一定的顺序,比如(c=a+b;)执行这个代码之前要求我们首先计算出a和b的值,再去计算c的值。再比如上面的P1,P2进程,我们要求代码4要基于代码的程序运行,那么我们就要保证代码4一定实在代码2之后才会执行

         这就是所谓的进程同步问题,让本来异步并发的进程互相配合,有序推进

    2.实现进程同步的方法

  用信号量实现进程同步:

1.分析为什么要实现”同步关系“,即必须保证”一前一后“执行的两个操作(或两句代码)

2.设置同步信号量S,初始值为0

3.在实现 ”前操作“之后执行 V(S)            ------- signal 的加操作

4.在实现 ”后操作“之前执行 P(S)            --------wait   的 减操作

还是上面的P1 P2进程,要求还是代码4要在代码2执行之后再执行,利用下面的方法即可实现

/*信号量机制实现同步*/
semaphore S=0;        //初始化同步信号量 

P1(){               
	代码1;
	代码2;
	V(S);
	代码3; 
} 
P2(){    
	P(S);           
	代码4;
	代码5;
	代码6; 
} 

分析:

情况一:若先执行到V(S) 操作,则S++后,S=1,之后执行到P(S)操作时,由于S=1,表示用可用的资源,会执行S--,

S的值变回到0,P2进程不会执行block原语,而是继续往下执行代码4。符合题意

情况二:若先执行到P(S)操作,由于S=0,S--后,表示此时没有可用资源,因此P操作中会执行block原语,主动请求阻塞,之后当执行完代码2,继而执行V(S)操作,S++,使S变回到0,由于此时又进程在该信号量的阻塞队列中,因此会在V操作中执行wakeup原语,唤醒P2进程,这样P2进程就可以继续执行代码4了。符合题意

上面两种情况保证了代码4执行前代码2肯定已经执行了

猜你喜欢

转载自blog.csdn.net/weixin_44820625/article/details/106077770