pthreads 生产者-消费者死锁

发布于 2024-09-30 09:34:19 字数 1576 浏览 9 评论 0原文

我编写了以下代码:

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;
}

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

有什么建议吗?

I wrote following code:

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;
}

All variables are properly initialized. The task is to produce JOB_SIZE elements and to consume them. From time to time it gets stuck in the dead lock. I am quite new to the posix threads so I am probably missing something very obvious (did producers/consumers many times in java/C#/python but now I am really stuck). I know it is much easier to do it with semaphores but I need to do it in this way.

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冰之心 2024-10-07 09:34:19

您在双方都使用了 cond_empty 进行等待。你发出信号(但从不等待)cond_full。

You used cond_empty in both sides for the wait. You signal (but never wait on) cond_full.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文