Нужно ли вызывать sleep, когда критические секции находятся в циклах, чтобы избежать тупиков? - PullRequest
3 голосов
/ 06 марта 2012

Соответствующие фрагменты кода из двух программ приведены ниже.По сути, потребитель вытесняет целое число из общего буфера, а производитель помещает целое число в командную строку.Без вызова спать в конце цикла возникает тупик.То есть оба процесса, кажется, ожидают семафор.Я не понимаю, как это могло произойти, и был бы признателен за объяснение.Кроме того, дайте мне знать, если есть подходящая альтернатива моему «сну, чтобы позволить другому процессу получить шанс».Моя интуиция говорит мне, что должно быть, и это было главной причиной, по которой я решил опубликовать этот вопрос.

Потребитель:

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 ]

2 голосов
/ 06 марта 2012

Если вы хотите заставить поток / процесс выдавать ЦП, вы можете использовать sched_yield . Сон заставит вызывающий поток ждать, даже если он может продолжаться, скажем, через 0,2 секунды. Конечно, это не для того, чтобы избежать условий гонки, вам нужны семафоры для синхронизации.

0 голосов
/ 18 апреля 2013

То, что вы здесь не определили, является частью ввода вашего кода.Вы должны быть осторожны при реализации многопоточного проектирования при использовании ввода-вывода, и вы должны быть особенно осторожны в отношении функций, которые вы выбираете для вызова в критических секциях.

В этой части кода вы вызываете atoi () в обеих критических секциях, поэтому я бы сказал, что вы должны попробовать очистить функциональность от ваших критических секций, пока проблема не будет решена, чтобы дать вам лучшее представлениегде ваш код имеет проблемы.

0 голосов
/ 06 марта 2012

В целом, любой ответ на вопрос о синхронизации процессов, связанный с использованием sleep (), является неправильным.Никогда не делай этого.В лучшем случае вы будете вызывать ошибки производительности, в худшем - проблемы инверсии приоритетов и взаимоблокировок.

Код, который вы написали (без сна!), Выглядит для меня разумной попыткой взаимного исключения, и он должен работать,Если вы хотите, чтобы другой процесс проснулся первым, вам нужно использовать два семафора: один для «передачи куки» в каждом направлении.

...