C: Threading semaphore_wait против цикла while - PullRequest
4 голосов
/ 20 января 2011

Есть ли какая-либо разница между следующими фрагментами кода с точки зрения использования процессора.

void *ManageSequencer(void *argument){
  SomeClass *someClass = (SomeClass *)argument;

  while (someClass->ThreadIsAlive()) {

    while(someClass->isAsleep) { }

    someClass->isAsleep = true;

    //thread execution statements 

  }
  return argument;
}

, где некоторые классы периодически устанавливают isAsleep=false, когда потоку требуется выполнить

ИЛИ

void *ManageSequencer(void *argument){
  SomeClass *someClass = (SomeClass *)argument;

  while (someClass->ThreadIsAlive()) {

    semaphore_wait(sem);

    //thread execution statements 

  }
  return argument;
}

, когда someClass периодически вызывает semaphore_signal(sem);, когда ему требуется выполнение потока.

Этот вопрос не об атомарности, а о том, вызовет ли цикл while больше работы процессора, чемсемафорное решение.Есть ли у семафора просто цикл while, который блокирует, пока не будет выполнено условие (приращение семафора выше нуля)?

Ответы [ 3 ]

3 голосов
/ 20 января 2011

Да, первый вызовет большую нагрузку на процессор, чем второй.По сути, всякий раз, когда активный поток в первом примере будет запланирован, он будет просто поглощать все свое время процессора, крутящееся на этом условии, пока планировщик не вытеснит его и не даст время другому потоку.Это означает, что у вас есть переключение контекста, и весь (потенциально) временной отрезок потока используется каждый раз на 100%, и он фактически не работает.

Второй пример захватит поток в ядре, поэтому он не будетполучить любое время процессора, пока ядро ​​не получит сигнал и не возобновит поток.Как только это произойдет, планировщик снова предоставит ему время обработки, но теперь мы знаем, что у него есть реальная работа вместо того, чтобы использовать весь его временной интервал, привязывающий ЦП.

2 голосов
/ 20 января 2011

Ваш первый пример будет занят вращением во внешнем цикле, когда someClass->isAsleep ложно.т. е. он потратит все процессорное время, потраченное на бездействие.

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

2 голосов
/ 20 января 2011

Типичная реализация семафора будет "парковать" поток в ядре, поэтому он не использует процессорное время. Настоятельно рекомендуется по этой причине:)

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

...