【发布时间】:2016-07-10 15:19:14
【问题描述】:
以下是示例消费者/生产者模型的代码:
int buffer[MAX];
int fill_ptr = 0;
int use_ptr = 0;
int count = 3;
void put(int value) {
buffer[fill_ptr] = value;
fill_ptr = (fill_ptr + 1) % MAX;
count++;
}
int get() {
int tmp = buffer[use_ptr];
use_ptr = (use_ptr + 1) % MAX;
count--;
return tmp;
}
cond_t empty, fill;
mutex_t mutex;
void *producer(void *arg) {
int i;
for (i = 0; i < loops; i++) {
pthread_mutex_lock(&mutex); // p1
while (count == MAX) // p2
pthread_cond_wait(&empty, &mutex); // p3
put(i);// p4
pthread_cond_signal(&fill); // p5
pthread_mutex_unlock(&mutex); // p6
}
}
void* consumer(void *arg) {
int i;
for (i = 0; i < loops; i++) {
pthread_mutex_lock(&mutex); // c1
while (count == 0) // c2
pthread_cond_wait(&fill, &mutex); // c3
int tmp = get(); // c4
pthread_cond_signal(&empty); // c5
pthread_mutex_unlock(&mutex); // c6
printf("%d\n", tmp);
}
}
但是,我认为这里有问题。假设 MAX=3,并且最初缓冲区已满(count = 3),那么消费者可以执行get() 并向生产者发出信号。生产者收到信号后,唤醒并开始执行缓冲区[0]中的put(),并持有互斥锁。
假设生产者刚刚卡在put();那么即使剩余 2 个资源,消费者也无法继续(因为互斥锁由生产者持有)。
我的理解正确吗?如果是这样,那是不公平的,因为还有 2 个资源可以消耗。
【问题讨论】:
-
假设生产者刚刚卡在 put() “医生,我这样做的时候很痛!” ——“那么,不要这样做”。不要取消引用空指针。不要导致缓冲区溢出。不要让持有互斥锁的线程卡住。
-
谨慎使用“信号”一词。它在 POSIX 系统中具有特定含义,与您修改条件和互斥锁时发生的情况无关。
标签: c