Intereting Posts
Как работает strcpy_s? Какая встроенная firebase database, способная на 100 миллионов записей, имеет эффективный C или C ++ API Неожиданное повторение с использованием fgets и sscanf Каковы формальные и практические ограничения на значения в «struct lconv», описывающие локаль? Распределение динамической памяти ANSI C и когда мы должны освобождать память Оптимизируйте массив трибунов для пространства Поиск строки в массиве символов строк в C Как много способов объявить String в C? (нужна помощь по модификаторам и масштабам) почему мы не можем назначить новую строку массиву, но указателю write () для вывода stdout и printf не чередуется? Как я могу получить исходные строки inline с выходом сборки с помощью GCC? Является ли WSASend с IOCP? C для производительности или размера кода – помимо того, что делает компилятор libxml в stdout при использовании библиотеки fastcgi Следующий указатель, возвращаемый malloc (0)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Сон (int milliSeconds)

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

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

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

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

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