Delphi - настройка времени ожидания потока

Asked
Viewd5997

7

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

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

Однако я не знаю, как настроить время сна. Я не хочу, чтобы петли длились вечно, поэтому период сна не может быть слишком длинным. Я выставляю 2 миллисекунды на каждой итерации (в каждом потоке) (почему 2 мс? - хороший вопрос :)).

С другой стороны, я подумал, что могу продлить время сна, но вызывать сон только один раз каждые n итераций (скажем, Sleep (100) каждые 50 итераций). Какой подход выбрать? Один цикл цикла занимает около 30 мс каждый (без ожидания).

Пожалуйста, сообщите.

Спасибо!
Мариуш.

4 ответов

9

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

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

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

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

    dummzeuch07 июня 2009, 08:43
  • Верно, но именно поэтому я написал, что приоритет фонового потока можно снизить, чтобы другие приложения (или основной поток) оставались отзывчивыми, но при этом использовали весь потенциал системы. В современных (многоядерных) системах поддержание достаточной загрузки всех ядер - гораздо большая проблема, чем отсутствие реакции приложения переднего плана. И в любом случае массивные неоптимизированные операции ввода-вывода представляют собой гораздо большую угрозу для удобства использования системы, чем высокая загрузка процессора.

    mghie07 июня 2009, 09:34
3

Вам лучше просто создать потоки с низким приоритетом и позволить им работать без сна, иначе вы не используете полную мощность процессора. Например, в многоядерных / многопроцессорных системах. Или, если ваша система на 100% простаивает: зачем ждать или спать?

Но если вам нужно немного сна, обратите внимание, что sleep (1) ждет 10-15 мс (!) из-за временного интервала Windows по умолчанию. Вы можете использовать timeBeginPeriod (1) модуля MMSystem.pas, чтобы установить разрешение в 1 мс :-) (я использовал это для последовательной связи).

2

Для управления потоками могут быть лучшие подходы, чем использование сна. Поскольку ваш вызов базы данных может возвращать 1-1000 записей для обработки, может иметь смысл разделить ваше приложение на два уровня, возможно, используя очередь сообщений для буферизации запросов. Ваше приложение может вызвать службу данных, а затем служба данных выполнит запрос и отправит отдельные сообщения с данными (или блоки сообщений и т. Д.) В очередь. Затем ваше приложение может создавать столько потоков, сколько необходимо для обработки сообщений. Больше потоков означает более быструю обработку за счет ЦП, но вы можете настроить это, чтобы получить правильный баланс.