Штрафы сценария постоянно зацикливаются на заднем плане - PullRequest
0 голосов
/ 23 апреля 2009

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

Я пытаюсь написать демон для очереди заданий для архивирования файлов в zip-файлы для веб-приложения, над которым я работаю. Это будет вести себя примерно так:

while True:
    while morejobs():
        zipfile()
    sleep(15seconds)

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

Редактировать:

Похоже, большинство ответов касается продолжительности сна. Я слепо включил его (в примере кода) на 15 миллисекунд за раз. На самом деле я рассчитывал на 15 секунд, и я «обновил» код, чтобы отразить это.

Снова отредактируйте:

Какое минимальное разумное время для сна сценария? 5 секунд до низкого уровня? Я понятия не имею, какова будет загрузка этого приложения или как часто новые задания будут добавляться в очередь.

Ответы [ 8 ]

4 голосов
/ 23 апреля 2009

Сон не требует накладных расходов. ОС Linux использует очень простой сигнал для пробуждения спящего процесса.

То, что вы показываете, - это шаблон проектирования "ожидание занята".

Чтобы устранить накладные расходы, вы хотите, чтобы вас разбудили ТОЛЬКО, когда есть работа.

Способы сделать это.

  1. Ждите чтения.

  2. Ожидание вызова выбранной функции. Смотри http://docs.python.org/library/select.html

  3. Подождите, пока будет снята блокировка. См http://docs.python.org/library/posixfile.html.

Из них ожидание чтения, пожалуй, самое простое. Чтение из канала или сокета - это то, что вы хотите сделать.

Я предполагаю, что у вас есть шаблон проектирования "несколько писателей - один читатель". В этом случае есть два варианта решения.

  1. Несколько запросов на сокет. Это решение, похожее на FTP, где вы пишете простой сервер, который прослушивает соединения в одном сокете и открывает выделенное соединение для каждого клиента. Затем вы используете select, чтобы определить, какой клиент отправляет файл.

  2. Один запрос на сокет. Это HTTP-подобное решение, когда вы получаете запросы в некотором сокете, а запрос представляет собой большой поток данных. Когда запрос завершен, сокет закрывается, так что другой клиент может его получить.

В этих двух случаях вы не спите - вы ожидаете завершения ввода-вывода.

1 голос
/ 24 апреля 2009

В качестве альтернативы вы можете понизить приоритет вашего процесса. (Я только знаком с методом Windows)

В Windows:

def setpriority(pid=None,priority=1):
    """ Set The Priority of a Windows Process.  Priority is a value between 0-5 where
        2 is normal priority.  Default sets the priority of the current
        python process but can take any valid process ID. """

    import win32api,win32process,win32con

    priorityclasses = [win32process.IDLE_PRIORITY_CLASS,
                       win32process.BELOW_NORMAL_PRIORITY_CLASS,
                       win32process.NORMAL_PRIORITY_CLASS,
                       win32process.ABOVE_NORMAL_PRIORITY_CLASS,
                       win32process.HIGH_PRIORITY_CLASS,
                       win32process.REALTIME_PRIORITY_CLASS]
    if pid == None:
        pid = win32api.GetCurrentProcessId()
    handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, pid)
    win32process.SetPriorityClass(handle, priorityclasses[priority])

из: http://code.activestate.com/recipes/496767/

1 голос
/ 23 апреля 2009

Если для получения файла требуется (а эти цифры приведены в качестве примера) 20 секунд, а для его обработки - 5 секунд, то какой вред в вашем процессе ждет в среднем еще 7,5 секунд, прежде чем он обнаружит, что файл есть?

Спящий процесс должен иметь максимально близкое к нулю влияние на процессор, насколько это возможно.

Так что нет, я бы вообще не беспокоился об этом аспекте.

Единственное, о чем вы должны беспокоиться, это о том, как автоматически перезапустить процесс в случае его сбоя. Я бы запускал задание cron каждые 5 минут (по выбору фактической частоты), чтобы уничтожить старую копию (вежливо и только если она запущена), а затем запустить новую. Таким образом, время простоя будет не более 5 минут, если что-то пойдет не так.

Я говорю вежливо, потому что старый может быть в середине обработки файлов, и вы не должны прерывать это, если это не подлежит восстановлению.

1 голос
/ 23 апреля 2009

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

1 голос
/ 23 апреля 2009

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

  • Обработка доступных файлов
  • Проверять наличие новых файлов каждые 60 секунд или через любой интервал, который вы выберете
  • Когда поступает новый файл, обрабатывайте его и любые другие, которые могли прибыть после последнего интервала
0 голосов
/ 24 апреля 2009

«Тысяча аргументированных мнений стоит одного измерения».

Просто попробуйте.

0 голосов
/ 23 апреля 2009

Помимо стоимости забивания вашего процессора, есть стоимость вызова morejobs () . Вы можете уменьшить это, используя более высокое значение для sleep () , или можете использовать какой-либо почтовый ящик, который получает запросы и затем запускает операцию zipfile () .

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

0 голосов
/ 23 апреля 2009

Это может взорвать ваш процессор, даже когда нечего обрабатывать.

Редактировать: На самом деле sleep() принимает аргумент в виде количества секунд, а не миллисекунд, поэтому я не думаю, что процессор будет проблемой. Тем не менее, возможно, вы могли бы использовать задание cron, чтобы запланировать что-то вроде этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...