17-信号量实现互斥、同步、前驱关系

信号量实现互斥、同步、前驱关系

信号量机制实现进程互斥

  1. 分析并发进程的关键活动,划定临界区(如:对临界资源打印机的访问就应该放在临界区)
  2. 设置互斥信号量mutex,初值为1
  3. 在临界区前执行P(mutex)
  4. 在临界区后执行V(mutex)

代码示例

/*信号量机制实现互斥*/
semaphor mutex=1;//初始化信号量
P1(){
···
P(mutex);//使用临界资源前需要加锁
临界区代码段
V(mutex);//使用临界资源后需要解锁
···
}
-----------------------------------------------------
P2(){
···
P(mutex);//使用临界资源前需要加锁
临界区代码段
V(mutex);//使用临界资源后需要解锁
···
}

注意点

  1. 对于不同的临界资源需要设置不同的互斥信号量。
  2. P、V操作必须成对出现
    1. 缺少P(mutex)就不能保证临界资源的互斥访问
    2. 缺少V(mutex)就会导致资源不被释放,等待进程永不被唤醒

信号量机制实现进程同步

进程同步:要让各并发进程按照要求有序的推进,互相配合。

用信号量实现进程同步

  1. 分析什么地方需要“同步关系”,即必须保证“一前一后”执行的两个操作(或两句代码)。
  2. 设置同步信号量S,初始化为0
  3. 在“前操作”之后执行V(S);
  4. 在“后操作”之前执行P(S);

代码示例

/*信号量机制实现同步*/
semaphore S=0;
P1(){
 代码1;
 代码2;
 V(S)
 代码3;
}
--------------------------------
P2(){
 P(S);
 代码4;
 代码5;
 代码6;
}

分析

  1. 若先执行V(S)操作,则S++后S=1;之后当执行到P(S)操作时,由于S=1,表示有可用资源,会执行S–,S的值变回0,P2进程不会执行block原语,而是继续往下执行代码4
  2. 若先执行P(S)操作,由于S=0,S–后S=-1,表示此时没有可用资源,因此P操作中会执行block原语,主动请求阻塞,之后当执行完代码2,继而执行V(S)操作,S++,使得S变回0,由于此时有进程在该信号量对应的阻塞队列中,因此会在V操作中执行wakeup原语,唤醒P2进程,此时P2就会继续执行代码4了

信号量机制实现前驱关系

进程P1有句代码S1,P2中有句代码S2,P3…P6中有句代码S6,这些代码可以按照如下前驱图所示关系来执行。17-信号量实现互斥、同步、前驱关系_第1张图片
其实每一对前驱关系都是一个进程同步的问题(需要保证一前以后的操作)
因此:

  1. 要为每一对前驱关系各设置一个同步变量
  2. 在“前操作”之后对相应同步变量执行V操作
  3. 在“后操作”之前对相应同步变量执行P操作

代码示例

17-信号量实现互斥、同步、前驱关系_第2张图片

你可能感兴趣的:(操作系统,c++,数据结构,面试)