Как я могу запустить и забыть процесс в Perl? - PullRequest
11 голосов
/ 25 января 2010

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

Ответы [ 4 ]

17 голосов
/ 25 января 2010

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


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

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

system("cmd &")

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

STDIN, STDOUT и STDERR совместно используются

И основной процесс, и основной процесс («ребенок») процесс) использовать одни и те же файловые дескрипторы STDIN, STDOUT и STDERR. Если оба пытаются получить к ним доступ сразу, могут случиться странные вещи. Вы возможно, захотите закрыть или снова открыть их для ребенка. Ты можешь получить вокруг этого с помощью "open" внутри канала (см. "open" в 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 для других примеров кода, чтобы сделать это. Зомби не проблема с "system (" prog & ")".

1 голос
/ 25 января 2010

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

0 голосов
/ 26 января 2010

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

0 голосов
/ 25 января 2010

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

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

Это запустит процесс перенаправления STDOUT и STDERR на / dev / null .

...