Вы можете использовать Perl различными способами для создания новых процессов в соответствии с вашими требованиями. В этом руководстве будет перечислено несколько важных и наиболее часто используемых методов создания и управления процессами Perl.
-
Вы можете использовать специальные переменные $$ или $ PROCESS_ID, чтобы получить текущий идентификатор процесса.
-
Каждый процесс, созданный с помощью любого из упомянутых методов, поддерживает свою собственную виртуальную среду с переменной % ENV .
-
Функция exit () всегда выходит только из дочернего процесса, который выполняет эту функцию, и основной процесс в целом не завершится, если не завершены все запущенные дочерние процессы.
-
Все открытые дескрипторы дублируются в дочерних процессах, поэтому закрытие любых дескрипторов в одном процессе не влияет на другие.
Вы можете использовать специальные переменные $$ или $ PROCESS_ID, чтобы получить текущий идентификатор процесса.
Каждый процесс, созданный с помощью любого из упомянутых методов, поддерживает свою собственную виртуальную среду с переменной % ENV .
Функция exit () всегда выходит только из дочернего процесса, который выполняет эту функцию, и основной процесс в целом не завершится, если не завершены все запущенные дочерние процессы.
Все открытые дескрипторы дублируются в дочерних процессах, поэтому закрытие любых дескрипторов в одном процессе не влияет на другие.
Оператор Backstick
Этот самый простой способ выполнения любой команды Unix — с помощью оператора backstick. Вы просто помещаете свою команду внутри оператора backstick, что приведет к ее выполнению и вернет ее результат, который можно сохранить следующим образом:
#!/usr/bin/perl @files = `ls -l`; foreach $file (@files) { print $file; } 1;
Когда приведенный выше код выполняется, он перечисляет все файлы и каталоги, доступные в текущем каталоге —
drwxr-xr-x 3 root root 4096 Sep 14 06:46 9-14 drwxr-xr-x 4 root root 4096 Sep 13 07:54 android -rw-r--r-- 1 root root 574 Sep 17 15:16 index.htm drwxr-xr-x 3 544 401 4096 Jul 6 16:49 MIME-Lite-3.01 -rw-r--r-- 1 root root 71 Sep 17 15:16 test.pl drwx------ 2 root root 4096 Sep 17 15:11 vAtrJdy
Функция system ()
Вы также можете использовать функцию system () для выполнения любой команды Unix, чей вывод будет отправлен на вывод сценария perl. По умолчанию это экран, т. Е. STDOUT, но вы можете перенаправить его в любой файл, используя оператор перенаправления> —
#!/usr/bin/perl system( "ls -l") 1;
Когда приведенный выше код выполняется, он перечисляет все файлы и каталоги, доступные в текущем каталоге —
drwxr-xr-x 3 root root 4096 Sep 14 06:46 9-14 drwxr-xr-x 4 root root 4096 Sep 13 07:54 android -rw-r--r-- 1 root root 574 Sep 17 15:16 index.htm drwxr-xr-x 3 544 401 4096 Jul 6 16:49 MIME-Lite-3.01 -rw-r--r-- 1 root root 71 Sep 17 15:16 test.pl drwx------ 2 root root 4096 Sep 17 15:11 vAtrJdy
Будьте осторожны, когда ваша команда содержит переменные среды оболочки, такие как $ PATH или $ HOME. Попробуйте следующие три сценария —
#!/usr/bin/perl $PATH = "I am Perl Variable"; system('echo $PATH'); # Treats $PATH as shell variable system("echo $PATH"); # Treats $PATH as Perl variable system("echo \$PATH"); # Escaping $ works. 1;
Когда приведенный выше код выполняется, он дает следующий результат в зависимости от того, что установлено в переменной оболочки $ PATH.
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin I am Perl Variable /usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
Функция fork ()
Perl предоставляет функцию fork (), которая соответствует системному вызову Unix с тем же именем. На большинстве Unix-подобных платформ, где доступен системный вызов fork (), Perl fork () просто вызывает его. На некоторых платформах, таких как Windows, где системный вызов fork () недоступен, Perl может быть построен для эмуляции fork () на уровне интерпретатора.
Функция fork () используется для клонирования текущего процесса. Этот вызов создает новый процесс, выполняющий ту же программу в той же точке. Он возвращает дочерний pid родительскому процессу, 0 — дочернему процессу или undef, если ответвление не выполнено.
Вы можете использовать функцию exec () внутри процесса для запуска запрошенного исполняемого файла, который будет выполняться в отдельной области процесса, и exec () будет ожидать его завершения, прежде чем завершить работу с тем же состоянием выхода, что и у этого процесса.
#!/usr/bin/perl if(!defined($pid = fork())) { # fork returned undef, so unsuccessful die "Cannot fork a child: $!"; } elsif ($pid == 0) { print "Printed by child process\n"; exec("date") || die "can't exec date: $!"; } else { # fork returned 0 nor undef # so this branch is parent print "Printed by parent process\n"; $ret = waitpid($pid, 0); print "Completed process id: $ret\n"; } 1;
Когда приведенный выше код выполняется, он дает следующий результат —
Printed by parent process Printed by child process Tue Sep 17 15:41:08 CDT 2013 Completed process id: 17777
Wait () и waitpid () могут быть переданы как идентификатор псевдопроцесса, возвращаемый fork (). Эти вызовы будут должным образом ожидать завершения псевдопроцесса и возвращать его статус. Если вы разветвляетесь, не дожидаясь своих детей, используя функцию waitpid () , вы будете накапливать зомби. В системах Unix вы можете избежать этого, установив для $ SIG {CHLD} значение «IGNORE» следующим образом:
#!/usr/bin/perl local $SIG{CHLD} = "IGNORE"; if(!defined($pid = fork())) { # fork returned undef, so unsuccessful die "Cannot fork a child: $!"; } elsif ($pid == 0) { print "Printed by child process\n"; exec("date") || die "can't exec date: $!"; } else { # fork returned 0 nor undef # so this branch is parent print "Printed by parent process\n"; $ret = waitpid($pid, 0); print "Completed process id: $ret\n"; } 1;
Когда приведенный выше код выполняется, он дает следующий результат —
Printed by parent process Printed by child process Tue Sep 17 15:44:07 CDT 2013 Completed process id: -1
Функция kill ()
Функция Perl kill (‘KILL’, (Process List)) может быть использована для завершения псевдопроцесса путем передачи ему идентификатора, возвращаемого fork ().
Обратите внимание, что использование kill (‘KILL’, (Process List)) в псевдопроцессе () может обычно вызывать утечки памяти, поскольку поток, реализующий псевдопроцесс, не получает возможности очистить свои ресурсы.
Вы можете использовать функцию kill () для отправки любого другого сигнала целевым процессам, например, следующая команда отправит SIGINT идентификаторам процессов 104 и 102 —