代码之家  ›  专栏  ›  技术社区  ›  Klark

pthreads生产者消费者死锁

  •  0
  • Klark  · 技术社区  · 14 年前

    我写了以下代码:

    void *produce(void* arg)
    {
     buffer* buff = (buffer *) arg;
     while (1)
     {
      pthread_mutex_lock(&mutex);
      if (elements_produced == JOB_SIZE)
      {
       pthread_mutex_unlock(&mutex);
       pthread_exit(NULL);
      }
      elements_produced++;
    
      while (buff->in_buff == CAPACITY)
      {
       pthread_cond_wait(&cond_empty, &mutex);
      }
    
      // produce
      buff->buffer[buff->tail] = rand();
      sum_produced += buff->buffer[buff->tail];
      printf(">produced %d\n", buff->buffer[buff->tail]);
    
      buff->tail = (buff->tail + 1) % CAPACITY;
      buff->in_buff++;
      pthread_cond_signal(&cond_empty);
      pthread_mutex_unlock(&mutex);
     }
     pthread_exit(NULL);
    }
    
    void *consume(void* arg)
    {
     int rc;
     buffer* buff = (buffer *) arg;
     while (1)
     { 
      rc = pthread_mutex_lock(&mutex);
    
      if (elements_consumed == JOB_SIZE)
      {
       pthread_mutex_unlock(&mutex);
       pthread_exit(NULL);
       return 0;
      }
      elements_consumed++;
    
      while (buff->in_buff == 0)
      {   
       rc = pthread_cond_wait(&cond_empty, &mutex);
      }
    
      // consume  
      printf("<consumed %d\n", buff->buffer[buff->head]);
      sum_consumed += buff->buffer[buff->head];
      buff->head = (buff->head + 1) % CAPACITY;
      buff->in_buff--;
      pthread_cond_signal(&cond_full);
      pthread_mutex_unlock(&mutex);
     }
     pthread_exit(NULL);
     return 0;
    }
    

    所有变量都已正确初始化。任务是生成作业大小的元素并使用它们。它不时地被锁在死锁里。我对posix线程还很陌生,所以我可能遗漏了一些非常明显的东西(java/C#/python中的生产者/消费者做过很多次,但现在我真的陷入了困境)。我知道用信号量做要容易得多,但我需要用这种方法。

    有什么建议吗?

    1 回复  |  直到 14 年前
        1
  •  3
  •   Ben Jackson    14 年前

    你在两边都用空空调等着。你发出信号(但不要等待)秒满。