有没有办法用 2 个信号量来解决生产者-消费者问题?

Is there a way to do the producer-consumer problem with 2 semaphores?

这是使用 3 个信号量的解决方案。想知道是否有办法用更少的东西来做,如果没有,为什么不呢?

   sem_t full; // # of filled slots
   sem_t empty; // # of empty slots
   sem_t mutex; // mutual exclusion

   sem_init(&full, 0, 0);
   sem_init(&empty, 0, N);
   sem_init(&mutex, 0, 1);

   Producer(){
      sem_down(empty);
      sem_down(&mutex);
      // fill a slot
      sem_up(&mutex);
      sem_up(full);
   }

   Consumer() {
      sem_down(full);
      sem_down(&mutex);
      // empty a slot
      sem_up(&mutex);
      sem_up(empty);
   }

避免互斥的唯一方法是信号量内的所有操作都是原子的(很少见)。互斥锁是为了确保危险位一次发生一个而不会被中断。

想象一下,如果您有两个线程试图做一些相互依赖的事情。

Thread 1:  Add 3 to the ordered list
Thread 2:  Add 4 to the ordered list
List:  { 1, 2, 5, 7}

线程 2 在插入他自己的号码之前需要查看线程 1 将他的号码贴在哪里。因此,我们使用互斥锁来确保一次只有一个线程尝试将其编号插入列表。

您的示例(以及其他在线示例)中的编写方式可能让人相信整个过程需要在互斥体中进行。如果你这样做,一次只能有一个线程工作!实际上,你会做一些不依赖于互斥量之外但信号量内部的其他线程的事情(比如生成一个随机数)并且只保护将数字插入列表中。

semaphore(x)
long_expensive_computation
mutex(y)
order_critical_stuff
release(y)
release(x)