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

使用pthread_cond_signal的生产者-消费者程序为何卡死?

生产者-消费者模型在n=1/2时卡死的问题求助

我用C语言的pthread库编写生产者-消费者程序,程序需要在限制n内生产和消费数据。但当n=1或n=2时,程序通常很快就会卡死——具体表现为停止输出'('或')',需要手动退出。

已制作最小可复现示例,测试发现n=1或2时会出现明显异常,n≥3时运行正常。

核心代码

#include "thread.h"
#include <semaphore.h>

int n, count = 0;

pthread_mutex_t lk = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;


void Tproduce(){
        while(1){
                pthread_mutex_lock(&lk);
                while(count == n){
                        pthread_cond_wait(&cv,&lk);
                }
                assert(count != n);
                printf("(");
                count++;
                //printf("%d\t", count);
                pthread_cond_signal(&cv);
                pthread_mutex_unlock(&lk);
        }
}


void Tconsume(){
        while(1){
                pthread_mutex_lock(&lk);
                while(count == 0){
                        pthread_cond_wait(&cv,&lk);
                }
                assert(count != 0);
                printf(")");
                count--;
                //printf("%d\t",count);
                pthread_cond_signal(&cv);
                pthread_mutex_unlock(&lk);
        }
}



int main(int argc, char* argv[]){
        assert(argc==2);
        n=atoi(argv[1]);
        setbuf(stdout,NULL);
        for(int i = 0; i < 8; i++){
                create(Tproduce);
                create(Tconsume);
        }
}

其中create是自制线程池中的线程创建函数,已验证可用。

尝试过的方案与疑问

我尝试使用pthread_cond_broadcast或两个独立的条件变量时,程序均可正常运行,但无法理解为何使用pthread_cond_signal会导致卡死。

按逻辑至少应有一个线程能正常工作,所有阻塞线程都应有被唤醒的机会。即使生产者或消费者线程被错误唤醒并尝试获取锁,也会因不满足条件而重新进入等待,让其他线程有机会获取锁。因此无论最坏情况如何,都不应完全卡死。

运行环境

  • WSL2下的Ubuntu 20
  • 编译器为gcc 9.4.0

补充:thread.h头文件代码

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdatomic.h>
#include <assert.h>
#include <unistd.h>
#include <pthread.h>

#define NTHREAD 64
enum { T_FREE = 0, T_LIVE, T_DEAD, };
struct thread {
  int id, status;
  pthread_t thread;
  void (*entry)(int);
};

struct thread tpool[NTHREAD], *tptr = tpool;

void *wrapper(void *arg) {
  struct thread *thread = (struct thread *)arg;
  thread->entry(thread->id);
  return NULL;
}

void create(void *fn) {
  assert(tptr - tpool < NTHREAD);
  *tptr = (struct thread) {
    .id = tptr - tpool + 1,
    .status = T_LIVE,
    .entry = fn,
  };
  pthread_create(&(tptr->thread), NULL, wrapper, tptr);
  ++tptr;
}

void join() {
  for (int i = 0; i < NTHREAD; i++) {
    struct thread *t = &tpool[i];
    if (t->status == T_LIVE) {
      pthread_join(t->thread, NULL);
      t->status = T_DEAD;
    }
  }
}

__attribute__((destructor)) void cleanup() {
  join();
}

恳请各位提供思路或解决方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 20:13:15