Как я могу разветвить фоновые процессы из CGI-скрипта Perl в Windows? - PullRequest
6 голосов
/ 05 сентября 2008

У меня были некоторые проблемы с разветвлением процессов из сценария Perl CGI при работе в Windows. Кажется, основная проблема заключается в том, что «форк» эмулируется при запуске в Windows и фактически не создает новый процесс (просто другой поток в текущем). Это означает, что веб-серверы (например, IIS), ожидающие завершения процесса, продолжают ожидать, пока не завершится «фоновый» процесс.

Есть ли способ отключить фоновый процесс из CGI-скрипта под Windows? Еще лучше, есть ли одна функция, которую я могу вызвать, которая сделает это кросс-платформенным способом?

(И просто для того, чтобы сделать жизнь более сложной, я действительно хотел бы хороший способ перенаправить вывод разветвленных процессов в файл одновременно).

Ответы [ 5 ]

9 голосов
/ 05 сентября 2008

Если вы хотите сделать это независимым от платформы способом, Proc :: Background , вероятно, лучший способ.

3 голосов
/ 05 сентября 2008

Использовать Win32 :: Process-> Create с параметром DETACHED_PROCESS

0 голосов
/ 11 марта 2018

Этот вопрос очень старый, и принятый ответ правильный. Тем не менее, я просто заставил это работать и решил добавить еще несколько подробностей о том, как это сделать, для всех, кому это нужно.

Следующий код существует в очень большом Perl CGI-скрипте. Эта конкретная подпрограмма создает билеты в нескольких системах продажи билетов, а затем использует возвращенные номера билетов для автоматического вызова через сервисы Twilio. Вызов занимает некоторое время, и я не хотел, чтобы пользователям CGI приходилось ждать, пока вызов не закончится, чтобы увидеть результат их запроса. Для этого я сделал следующее:

  (All the CGI code that is standard stuff.  Calls the subroutine needed, and then)

  my $randnum = int(rand(100000));
  my $callcmd = $progdir_path . "/aoff-caller.pl --uniqueid $uuid --region $region --ticketid $ticketid";
  my $daemon = Proc::Daemon->new(
    work_dir     => $progdir_path,
    child_STDOUT => $tmpdir_path . '/stdout.txt',
    child_STDERR => $tmpdir_path . '/stderr.txt',
    pid_file     => $tmpdir_path . '/' . $randnum . '-pid.txt',
    exec_command => $callcmd,
  );
  my $pid = $daemon->Init();

  exit 0;

  (kill CGI at the appropriate place)

Я уверен, что случайное число, сгенерированное и прикрепленное к pid, излишне, но я не заинтересован в создании проблем, которых очень легко избежать. Надеюсь, это поможет кому-то, кто хочет сделать то же самое. Не забудьте добавить use Proc::Daemon вверху вашего скрипта, отразить код и изменить пути и имена вашей программы, и вам будет хорошо идти дальше.

0 голосов
/ 27 октября 2008

Я обнаружил реальные проблемы с fork () в Windows, особенно при работе с объектами Win32 в Perl. Таким образом, если это будет зависеть от Windows, я действительно рекомендую вам взглянуть на библиотеку Thread внутри Perl.

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

0 голосов
/ 05 сентября 2008

perlfork

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

На некоторых платформах, таких как Windows где системный вызов fork () не доступно, Perl может быть построен для эмулировать fork () в интерпретаторе уровень. Пока эмуляция предназначена быть максимально совместимым с реальная вилка () на уровне программа Perl, есть определенные важные различия, которые вытекают из тот факт, что все псевдо ребенка `` процессы '', созданные таким образом, живут в тот же реальный процесс, насколько операционная система обеспокоена.

...