当关键部分处于循环中以避免死锁时,是否需要调用sleep?

时间:2012-03-06 17:38:59

标签: linux semaphore shared-memory

以下两个程序的相关代码片段。基本上,消费者从共享缓冲区中取出一个整数,生成器从命令行中排队整数。如果没有在循环结束时调用sleep,则会发生死锁。也就是说,两个进程似乎都在等待信号量。我不明白这是怎么发生的,并希望得到解释。另外,让我知道是否有一个适当的替代方案来让我的“睡眠让其他过程得到机会”解决方案。我的直觉告诉我应该有,这是我决定发布这个问题的主要原因。

消费者:

while (get_success == 0) {
  // critical section
  sem_wait(semaphore);
  if (*top != *bottom || *empty == 0) { // not empty
    printf("Stored Integer: %d\n", buffer[*bottom]);
    *bottom = (*bottom + 1) % N;
    if (*bottom == *top)
      *empty = 1;
    get_success = 1;
  }
  sem_post(semaphore);
  // end critical section
  if (get_success == 0)
    sleep(1);
}

制片:

while (ins_success == 0) {
  // critical section
  sem_wait(semaphore);
  if (*top != *bottom || *empty == 1) { // not full
    buffer[*top] = atoi(input);
    *empty = 0;
    *top = (*top + 1) % N;
    ins_success = 1;
  }
  sem_post(semaphore);
  // end critical section
  if (ins_success == 0)
    sleep(1);
}

谢谢!

3 个答案:

答案 0 :(得分:2)

如果要强制线程/进程产生CPU,可以使用sched_yield。睡眠将迫使调用线程等待,即使它可以继续,比如说,在0.2秒之后。当然,这不是为了避免竞争条件,你需要信号量来进行同步。

答案 1 :(得分:0)

从广义上讲,对涉及使用sleep()的进程同步问题的任何答案都是错误的。永远不要那样做。充其量你会产生性能错误,最坏的情况下你会看到优先级倒置和死锁问题。

你写的代码(没有睡觉!)看起来像是一个合理的互斥尝试,它应该有效。如果你想让其他进程先唤醒,你需要使用两个信号量:一个用于向每个方向“交换cookie”。

答案 2 :(得分:0)

此处未定义的是代码的“输入”部分。在使用I / O时,您必须小心实现多线程设计,并且您应该特别注意从关键部分中选择调用的函数。

在这部分代码中,你在两个关键部分调用atoi(),所以我会说你应该尝试从关键部分剥离功能,直到问题解决,让你更好地了解你的位置代码有问题。