Вопрос

Когда у вас сложный цикл опроса состояния чего-либо, я не совсем уверен, как выполнить опрос, не мешая другим процессам, желающим использовать центральный процессор.Например, делая это:

while (state == BUSY) state = check_state();

похоже на пустую трату ресурсов.Я бы подумал, что лучшим способом сделать это было бы:

while (state == BUSY) {
    sched_yield();
    state = check_state();
}

Я бы ожидал, что top перечислит процесс как спящий, даже если он потребляет 100% процессора во время выполнения этого.Таким образом, процесс опроса прошел бы (я надеюсь) "красиво".Но это не то, что происходит.На данный момент у меня есть

while (state == BUSY) {
    sleep(1);
    state = check_state();
}

что вполне приемлемо, но я чувствую, что это можно было бы сделать лучше, чем это.Существует ли стандартная практика для этого?

Это было полезно?

Решение

Не включайте sched_yield(), это очень сильно затрудняет определение приоритета планировщика, и даже если оно хорошо взаимодействует с точки зрения производительности, это приведет к таким вещам, как сокращение времени автономной работы и показателей энергопотребления.Если ваше приложение может переносить задержки, опрос с таймаутом (даже коротким, например, 10 Гц) очень предпочтителен, если все еще не идеален.

Правильный ответ зависит от того, что на самом деле нужно сделать check_state() .Вы абсолютно уверены, что не можете организовать все так, чтобы изменения вашего состояния были видимыми для ядра событиями, которые вы можете заблокировать?

Другие советы

Я не думаю, что это то, что вы можете использовать опрос или эполл включен?

К сожалению, не существует такого понятия, как добросовестный опрос.Опрос - это всегда компромисс между временем реакции и потреблением ресурсов:чем короче период опроса, тем лучше время реакции, но тем выше потребление ресурсов.Чем дольше период опроса, тем больше энергии вы экономите, но тем менее реактивным становится ваше приложение.

Опрос всегда уродлив, независимо от того, как вы на это смотрите.Если вы пытаетесь делать все правильно, вам придется использовать более совершенный механизм, т.е.уведомление.Это означает, что ваш API check_state() является плохим, потому что он позволяет вам опрашивать только состояние;вам нужна функция, предназначенная для уведомления вас об изменении состояния.Как правило, такая функция делает некоторый fd читаемым при изменении состояния, поэтому вы можете синхронно или асинхронно ожидать событий на fd и просыпаться только тогда, когда происходит такое событие.

Я думаю, вы могли бы использовать событие libevent или либев.

Оба предоставляют средства для обработки подобных вещей.

В моей работе в реальном времени я обычно выбираю разумный тайм-аут (например, 10us) и использую условие и RDTSC (счетчик временных меток).

Если вы хотите вращаться в течение действительно длительных периодов времени (например, дольше 10 мс), я бы посоветовал поместить туда небольшое указание sleep, чтобы другие материалы получили некоторый шанс для запуска.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top