进程同步-信号量机制

1、整型信号量

  • 除初始化外,仅能通过两个标准的原子操作wait(S)和signal(S)来访问,很长时间以来,这两个操作一直被称为P、V操作,wait和signal操作可描述如下

    wait(S){
      while (S<=0) {
        S--;
      }
    }
    signal(S){
      S++;
    }
    

2、记录型信号量

  • 在整型信号量机制中的wait操作,只要是信号量S<=0就会不断的测试,不满足让权等待的原则,所以,在信号量机制中出了需要有一个用于记录整型变量value外,还应该增加一个进程链表指针list,用于连接上述的所有等待进程。

    typedef struct{
      int value;
      struct process_control_block *list;
    }semaphore
    wait(semaphore *S){
      S->value--;
      if(S->value<0)block(S->list)
    }
    signal(semaphore *S){
      S->value++;
      if(S->value<=0)wakeup(S->list);
    }
    
  • 在本机制中,S->value为资源信号量(表示资源的数目)

  • 对他进行wait操作即P,意味着该资源数减少1,因此描述为S->value–;当检测到value<0是表示该类资源分配完毕,所以调用block原语,进行自我阻塞,并插入信号链表S->list中,可见,本机制遵循了让权等待的原则,此时value的绝对值表示阻塞的进程数。

  • 对信号量的每次signal操作即V操作,表示进程释放一个单位的资源,若value的值仍然<0(说明链表中仍然存在阻塞的进程)所以调用wakeup原语,将list中等待的一个进程唤醒。

3、AND型信号量

  • 对于多个进程访问多个临界资源会有可能发生死锁现象

  • AND同步机制的基本思想是:将进程在整个运行过程中所需要的所有资源,一次性全部的分配给进程,待进程使用完后再一起释放(要么全给,要么一个不给)这样就可以避免死锁的发生。

  • 所以AND型信号量应该这样

wait(s1,s2,s3,sn){
  if(s1>=1&&s2>1&&.....)
}
signal(s1,s2,s3,sn){
  s1++;
  s2++;
  ...
}

4、信号量集

  • 在记录型信号量中,每次让资源减少一个单位,效率比较低,切会增加死锁的概率。

  • 信号量集,就是为资源设置下限,ti,即要求Si>=ti否则不予分配

你可能感兴趣的:(操作系统)