You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pthread与信号量实现多生产者消费者问题最后消费卡住如何解决

故障原因
  • 消费者循环判断存在竞态:while (count < NO_ITEMS) 的判断是在持有互斥锁、调用sem_wait前执行的,此时共享变量count可能还未被其他消费者线程更新,会出现多个消费者同时通过判断进入循环的情况。生产者总共只会触发NO_ITEMS次sem_post(&fillCount),当进入循环的消费者数量超过剩余的fillCount信号量时,多余的线程会永久阻塞在sem_wait调用上。
  • 消费逻辑判断错误:代码中if (!items.empty() && count < NO_ITEMS - 1) 的条件限制了只有count小于99时才会消费商品,导致第100个商品永远不会被弹出处理。且count无论是否实际完成消费都会自增,进一步导致退出逻辑和信号量计数不匹配。
  • 全局count语义错误:当前count统计的是消费者进入临界区的次数,而非实际消费的商品总数,和生产端的总商品数无法对应,逻辑完全混乱。
修复方案

调整消费者逻辑,将消费计数、退出判断放到持有互斥锁之后执行,修正消费条件,同时处理阻塞消费者的唤醒逻辑,修改后的消费者函数参考如下:

void* thread_consumer(void* args) {
    while (1) {
        sem_wait(&fillCount);
        pthread_mutex_lock(&mutex);

        // 所有商品已消费完成,唤醒其他阻塞的消费者后退出
        if (count >= NO_ITEMS) {
            pthread_mutex_unlock(&mutex);
            sem_post(&fillCount);
            break;
        }

        // 正常消费逻辑,消费完成后再更新计数
        removeItem();
        count++;

        pthread_mutex_unlock(&mutex);
        sem_post(&emptyCount);
    }
    return nullptr;
}

修改后逻辑说明:

  1. 先通过sem_wait拿到可用商品的信号量,再进入临界区判断状态,避免无效的信号量等待。
  2. 临界区内判断如果所有商品已经消费完成,就主动post一次fillCount唤醒其他阻塞的消费者,避免其他线程永久等待。
  3. 移除错误的消费限制条件,只有实际完成消费才更新计数count,保证计数语义正确。

内容的提问来源于stack exchange,提问作者SugiuraAyano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 14:36:02