【问题标题】:Consumer/producer program got stuck消费者/生产者计划陷入困境
【发布时间】: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


【解决方案1】:

我的理解正确吗?

是也不是。

是的,如果producer 调用putput 被卡住(例如通过进入无限循环),consumer 将被卡住是正确的。

但是,您不能假设 there are 2 resources leftpthread_cond_signal 不承诺 producerconsumer 读取所有 3 个三个元素之前执行。您所能知道的是consumer 至少读取了一个元素,但在生产者执行之前它可能读取了 2 甚至 3。

如果是这样,那就太不公平了……

不,这不公平。这正是互斥锁的用途,即确保只有一个线程可以访问共享资源。

因此,重要的是要确保持有互斥锁的线程不会卡住!这是你作为程序员的责任。

注意:在你的情况下,里面没有任何东西会导致线程卡住。

【讨论】:

    【解决方案2】:

    假设生产者刚刚被困在 put();那么即使剩余 2 个资源,消费者也无法继续(因为互斥锁由生产者持有)。

    当你持有互斥锁时,你绝不能做一些会卡住的事情,而你的代码不会。

    【讨论】:

      猜你喜欢
      • 2019-08-19
      • 2018-08-26
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多