Может кто-нибудь, пожалуйста, скажите мне, как стрелять и забыть процесс в Perl? Я уже посмотрел на ruby: как запустить и забыть подпроцесс? для того, чтобы сделать то же самое в Ruby.
Как я могу запускать и забывать процесс в Perl?
Ответ 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 родителя ребенку (так что последний может опросить таблицу процессов - не рекомендуется).