Подтвердить что ты не робот

C Main Loop без 100% процессора

#include <stdio.h>

int main() {
  while(!DONE) {
    /* check for stuff */
  }
  return 0;
}

В приведенном выше примере кода используется 100% процессор, пока DONE не будет истинным. Как я могу реализовать программу, которая петли и только завершает работу, когда DONE, но которая не использует 100% процессор? Современные языки используют что-то вроде App.ProcessMessages или что-то в этом роде, чтобы дать ОС контроль на данный момент, а затем вернуться в цикл.

Я новичок в C, очевидно... используя последние GCC, linux и windows (портативное решение было бы здорово!)

4b9b3361

Ответ 1

Это зависит от того, что вы хотите сделать в этом цикле.

Если вы ожидаете внутри цикла (т.е. если нажата {сделайте что-то}, то ваш механизм потеряет системные ресурсы, ничего не давая взамен. Более быстрый процессор просто сделает больше простоя циклов. Это можно решить, ожидая событий Не просто sleep, но предпочтительно событие, которое запускает что-то значимое. Например, операция с файлом (stdin также является файлом) будет переносным механизмом. Это уступит место другим приложениям до тех пор, пока не будут доступны данные. может потребоваться погружение в семафоры или сигналы, которые часто зависят от ОС. Уровень абстракции может решить эту проблему.

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

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

Ответ 2

У вас есть несколько вариантов:

  • Используйте sleep(), чтобы заставить процесс периодически приостанавливаться и разрешить другому процессу использовать CPU
  • Запуск на более низком уровне приоритета - что приведет к тому, что ОС назначит меньшее время процессора
  • Использование мьютекса или другого объекта синхронизации для обнаружения, когда работа доступна, - что будет препятствовать процессу потреблять любое время ЦП, если оно фактически не выполняет работу.
  • Если вы получаете работу быстрее, чем можете ее обработать, вам все равно придется использовать какую-то модель сна/приоритета, чтобы полностью не использовать процессор.

Вариант №2 может быть сложно сделать в нейтральном режиме платформы/ОС. Лучше всего запустить этот процесс и изменить его приоритет в среде выполнения.

Ответ 3

Вашими двумя параметрами будут опрос и какое-то уведомление о событиях.

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

Другой вариант - подождать при условии POSIX или события Windows или что-то в этом роде. Изменяется не только этот код, но затем "материал, который вы проверяете", должен вызвать флаг, чтобы сказать, что это сделано. Это будет немного менее портативный код, хотя, вероятно, есть библиотеки для абстрагирования платформы. Но вы получите немедленные результаты для события и не потеряете время на процессор, проверяя вещи, которых там нет.

Ответ 4

Что именно вы проверяете?

Если вы проверяете что-то измененное с помощью аппаратного или другого процесса, просто вызовите sleep в свой цикл.

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

Ответ 5

Если я правильно понял, вы сказали в комментариях, что DONE можно изменить из других потоков. Если это так, переменные состояния имеют смысл. С pthreads можно было бы сделать:

В потоке, который ждет:

pthread_mutex_lock(&mutex);
while (!DONE) {
     pthread_cond_wait(&cond, &mutex);
}
pthread_mutex_unlock(&mutex);

В других потоках, когда DONE изменяется:

pthread_mutex_lock(&mutex);
DONE = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);

Ответ 6

использование

Сон (int миллисекунды)

Ответ 7

Sleep(0); было бы достаточно, я думаю,

Ответ 8

Используйте yield().

Ответ 9

Если я правильно угадываю (я не знаю об этом), эквивалент App.ProcessMessages блокирует IO. И поскольку я не знаю никакой реализации C в многозадачной ОС, которая использует опрос, любой стандартный C IO должен быть безопасным.

Ответ 10

В окнах вы можете использовать Sleep (int миллисекунды), определенный на windows.h.

Ответ 11

Сон (0); достаточно