2010-07-08 6 views
2

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

+1

Вам нужна дополнительная информация о том, что делает ваш сценарий, или, что более важно, пример кода. Если вы можете запустить/создать новый процесс, который будет менее интенсивным, вы можете освободить память в текущем процессе. – vol7ron

ответ

3

См. Watching long processes through CGI.

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

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

0

Да, вы можете запустить другой Perl-скрипт из Perl-скрипт, а затем выйти из сценария вызова:

http://perldoc.perl.org/functions/fork.html

Пример кода:

#!/usr/bin/perl 

my $pid = fork(); 
if (not defined $pid) { 
    print "resources not avilable.\n"; 
} elsif ($pid == 0) { 
    print "IM THE CHILD\n"; 
    sleep 5; 
    print "IM THE CHILD2\n"; 
    exit(0); 
} else { 
    print "IM THE PARENT\n"; 
    waitpid($pid, 0); 
} 
print "HIYA\n"; 

Но это не будет работать , если вы хотите, чтобы второй скрипт мог использовать CGI для связи с вашим веб-сервером/пользователем. Если вы используете Perl-скрипт как CGI, он должен вернуть результат пользователю.

Так у вас есть два пути решения этой проблемы:

  • попытаться выяснить, почему вы используете так много памяти и улучшить сценарий.

  • Если нет способа уменьшить потребление памяти, вы можете использовать демонизированный perl-скрипт как рабочий процесс, который выполняет вычисления и возвращает результаты в ваш CGI-perl-скрипт, который должен ждать для результата до прекращения.

+0

С 'fork()' вы теперь загрузили две копии программы (включая все данные, загруженные программой перед вилкой).Как это уменьшит объем памяти в сценарии? – mob

+0

на самом деле это работает, потому что ребенок наследует открытые дескрипторы файла от родителя, поэтому, когда ребенок записывает в stdout, он перейдет к тому же stdout, что и родительский, то есть к каналу, который веб-сервер открыл с помощью скрипта cgi. – miedwar

+0

fork() генерирует самостоятельный, независимый процесс (http://en.wikipedia.org/wiki/Fork_%28operating_system%29). Вы можете запускать разные скрипты с помощью fork, и поэтому каждая часть меньше как полная часть. Затем вам нужно управлять изменением данных между всеми процессами - никто не сказал, что это просто :) – Erik

1

Если применимо, сделайте вычисление/поколение выключенным.

создать демон или запланированное задание, которое создает статическую версию результатов, демон может создавать новую версию результатов событий (например, файлов, измененных) или в заданные интервалы.

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

Примечание стороны, если это не костюмы ваших потребностей, я бы отойти от CGI вообще и смотреть в mod_perl или fastcgi, где у вас есть постоянные процессы перл для обработки запросов, что экономит накладные расходы на разветвление нового Perl переводчицы, загрузочные модули и т. д.

Смежные вопросы