10.信号量 ||(Semaphore)

信号量实现同步


举个例子

  1. 在这里司机启动车辆需要售票员关车门,售票员开车门需要司机到站停车。
  2. 对于这两个线程来说
  • 需要设置两个semaphore d=0;semaphore c=0;
  • 为什么呢,因为有执行顺序的问题,只有售票员关门时候才可以启动车辆,设置一个d=0,司机启动汽车时候,这个线程执行p(d)来检测,当为d=0,会进入等待的状态。当售票员关门之后,这个线程执行V(d)操作,d++。这时司机执行p(d),就可以跳过等待状态,去启动车辆了。
  • 同时售票员开车门需要司机到站停车也是这个道理,还需要另一个semaphore c=0;
  1. 为什么初始化为0:
    阻塞机制: 信号量初始化为0是为了确保在相应的操作(如关闭门或到站停车)完成之前,相关的线程(如司机或售票员)会处于等待状态。这种初始化方式确保了操作的先后顺序,防止了例如司机在门未关闭时启动车辆的情况,从而确保了系统的安全性和正确性。
  2. 同步问题
  • 同步问题实质是将异步的并发进程按照某种顺序执行;
  • 解决同步的本质就是要找到并发进程的交互点,利用P操作的等待特点来调节进程的执行速度。
  • 通常初始值为0的信号量可以让进程直接进行等待状态,直到另一个进程唤醒他。

经典同步问题

生产消费者问题

  1. 生产者(p)与消费者(c)共用一个缓冲区,生产者不能往“满”的缓冲区中放产品,消费者不能从“空”的缓冲区中取产品。
Semaphore empty =1;//signal for producer
Semaphore empty=0;//signal for producer
Producer {
  while(true){
  make a product;
  P(empty);
  put the product into buffer;
  V(full);
}
}
Consumer{
  while(true){
  P(full);
  pick product from buffer;
  V(empty);
  consume the product;
}
}
  • 这种方式是按照一定顺序执行的。
  1. the bounded-buffer problem(有界缓冲区)
  • 有界缓冲区问题,两个线程“生产者”和“消费者”,同时使用一个固定长度的大小的缓冲区,生产者的主要是放入一定数量的数据到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。
  • producer_i或consumer_i中的i表明有多个生产者和消费者,在许多个生产和消费者线程中,还需要解决当多个生产线程同时进入临界区,多个消费线程进入临界区。这些情况还是需要使用互斥锁。
  • 重要注意事件
    • 不要随意扩大临界区
    • empty和full的p,v操作不在同一个进程(同步信号量)
    • mutex的p,v操作在同一个进程(互斥信号量)

苹果橘子问题

  • 问题描述
  • 解决方案
    • 需要去分析多个生产者和消费者之间的关系。首先是协作关系,生产苹果的与消费苹果的是协作关系,生产橘子与消费橘子是协作关系。生产苹果与橘子之间又是竞争关系。
    • 在代码中利用这种关系,V(sp)是消费者结束后,让生产者去竞争。这个方式刚好解决了问题。
posted @ 2024-04-26 10:46  zhudachang  阅读(12)  评论(0编辑  收藏  举报