有没有办法用 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)
这是使用 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)