Как запустить внешний процесс, не дожидаясь его завершения из сценария Perl CGI? - PullRequest
1 голос
/ 19 апреля 2010

Можно ли продолжить отображение HTML-кода CGI-скрипта, не дожидаясь завершения дочернего процесса, но дочерний процесс должен остаться в живых после завершения CGI-скрипта.

Вот что у меня есть,

- Показать HTML-страницу

# html страница настроена ... так что заголовок / другие вещи

# -c, -h - это просто парамы
system("perl subprocess.pm -c params -h 1 &");

# фактически распечатать настройки html-страницы
...

По какой-то странной причине он ожидает завершения подпроцесса, прежде чем выводит html-страницу, хотя я включил асинхронный системный вызов для linux. Он не отображает страницу сразу. Можно ли распечатать html-страницу, не дожидаясь завершения подпроцесса?

Ответы [ 3 ]

3 голосов
/ 19 апреля 2010
  1. Это возможно - пожалуйста, убедитесь, что автозапуск включен ($|=1;) , как описано здесь , или в этом отношении в "Поваренной книге Perl" (Глава 7.12. Промывка вывода).

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

  2. Однако это ненадежно и может быть легко взломано из-за тайм-аутов HTTP. Поэтому правильное решение для отображения постоянно меняющихся результатов на веб-странице:

    а. Более простое решение:

    • Ваш скрипт CGI печатает во временный файл HTML

    • время от времени он принимает этот временный файл, закрывает HTML и копирует текущую последнюю версию в какое-то временное местоположение, видимое из дерева htdocs (например, на которое может ссылаться клиент через URL-адрес - скажем, http://your_server/tmp/AYZ122.html

    • ваш исходный CGI генерирует HTTP-ответ, перенаправляющий на http://your_server/tmp/AYZ122.html после создания очень оригинальной версии временного файла и порождения дочернего процесса.

    • Временный HTML-файл в этом месте имеет META REFRESH, который указывает ему обновляться каждые N секунд (скажем, 10) и соответствующее сообщение / CSS для предупреждения пользователя о том, что идет загрузка, и, пожалуйста, подождите.

    б. Более сложное решение:

    • Несколько похоже на то, что основной скрипт CGI создает HTML-страницу «Пожалуйста, подождите», отправленную пользователю, и запускает дочерний процесс, который записывает временный файл.

    • Тем не менее, временный файл, созданный дочерним процессом, не обязательно представляет собой целую HTML-страницу, а представляет собой некоторый файл данных.

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

2 голосов
/ 04 июля 2010

Есть и другое решение: использовать SSI (включая серверную часть). Ваша CGI-программа:

  • 1) создает временную веб-страницу «Пожалуйста, подождите» содержит директиву #include виртуальный лог-файл;
  • 2) инициализирует лог-файл, например пишет там первое сообщение;
  • 3) тихо запускает основной подпроцесс;
  • 4) молча запускает подпроцесс проверки;
  • 5) создает веб-страницу с метатегом REFRESH с перенаправление на временную веб-страницу. Временная веб-страница имеет метатег REFRESH без перенаправления.

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

В результате лог-файл показывается пользователю и постоянно обновляется каждые N секунд до завершения основного подпроцесса.

0 голосов
/ 19 апреля 2010
...