Как я могу запускать и забывать процесс в Perl?

Может кто-нибудь, пожалуйста, скажите мне, как стрелять и забыть процесс в Perl? Я уже посмотрел на ruby: как запустить и забыть подпроцесс? для того, чтобы сделать то же самое в Ruby.

Ответ 1

От perlfaq8 ответ на Как мне начать процесс в фоновом режиме?


Несколько модулей могут запускать другие процессы, которые не блокируют ваш Perl программа. Вы можете использовать IPC:: Open3, Parallel:: Jobs, IPC:: Run и некоторые из модули POE. Подробнее см. CPAN.

Вы также можете использовать

system("cmd &")

или вы можете использовать fork, как описано в "fork" в perlfunc, с дальнейшим примеры в perlipc. Некоторые вещи, о которых нужно знать, если вы используете Unix- как система:

STDIN, STDOUT и STDERR являются общедоступными

Как основной процесс, так и фоновый ( "ребенок" ) процесс) используют одни и те же дескрипторы файлов STDIN, STDOUT и STDERR. Если оба пытаются получить к ним доступ сразу, могут произойти странные вещи. Вы может захотеть закрыть или вновь открыть их для ребенка. Вы можете получить вокруг этого "открыть" трубу (см. "открыть" в perlfunc), но на в некоторых системах это означает, что детский процесс не может пережить предок.

Сигналы

Вам придется поймать сигнал SIGCHLD и, возможно, SIGPIPE. SIGCHLD отправляется при завершении фонового процесса. SIGPIPE - отправляется, когда вы пишете файл-дескриптор, чей дочерний процесс закрыт (незафиксированный SIGPIPE может заставить вашу программу тихо умирать). Это не проблема с "system (" cmd & ")".

Zombies

Вы должны быть готовы "пожинать" дочерний процесс, когда он отделки.

   $SIG{CHLD} = sub { wait };

   $SIG{CHLD} = 'IGNORE';

Вы также можете использовать двойную вилку. Вы сразу же ждете() для своего первый ребенок, а демон init будет ждать() для вашего внука как только он выйдет.

   unless ($pid = fork) {
       unless (fork) {
           exec "what you really wanna do";
           die "exec failed!";
       }
       exit 0;
   }
   waitpid($pid, 0);

См. "Сигналы" в perlipc для других примеров кода для этого. Зомби не являются проблемой с "системой (" prog & ")".

Ответ 2

Если вы хотите демонизировать свой Perl script, я бы посмотрел на Proc:: Daemon.

Ответ 3

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

process_name > /dev/null 2>&1 &;

Это приведет к перенаправлению процесса STDOUT и STDERR на/dev/null.

Ответ 4

Если вы хотите, чтобы "дочерний" процесс сторожевого таймера исчез, когда "родительский" процесс завершается, вам не нужно, чтобы родительский процесс "запускал и забывал" дочерний процесс. Вам либо нужно использовать fork (как описано Brian d foy), либо передать PID родителя ребенку (так что последний может опросить таблицу процессов - не рекомендуется).