Управление процессами в Perl

В Perl можно создавать процессы разными способами.

В этом руководстве будут рассмотрены некоторые методы управления процессами.

  • Вы можете использовать специальную переменную$$или$PROCESS_IDдля получения идентификатора процесса.

  • Хеш %ENV хранит переменные окружения родительского процесса, то есть переменные окружения в оболочке. Эти переменные можно изменять в Perl.

  • exit()Обычно используется для завершения дочерних процессов; главный процесс завершается после завершения всех дочерних процессов.

  • Все открытые дескрипторы дублируются с помощью функции dup() в дочернем процессе, и закрытие любых дескрипторов в одном процессе не влияет на другие процессы.


Оператор обратных кавычек

Вы можете легко выполнять команды Unix с помощью оператора обратных кавычек. Вы можете вставлять некоторые простые команды внутри обратных кавычек. После выполнения команды возвращается результат:

#!/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
……

Функция system()

Вы также можете использовать функциюsystem()для выполнения команд Unix. При выполнении команды результат выводится напрямую. По умолчанию он отправляется туда, куда в данный момент указывает STDOUT в Perl, обычно на экран. Вы также можете использовать оператор перенаправления > для вывода в указанный файл:

Выполните приведённую выше программу, вывод будет следующим:

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
……

Нужно обращать внимание на результаты вывода, когда команды содержат переменные окружения, такие как $PATH или $HOME, как показано ниже:

Пример

#!/usr/bin/perl $PATH = "Я — переменная Perl"; system('echo $PATH'); # $PATH как переменная окружения оболочки system("echo $PATH"); # $PATH как переменная Perl system("echo \$PATH"); # Экранирование $ 1;

Выполните приведённую выше программу, вывод будет следующим:

/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
我是 Perl 的变量
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin

Функция fork()

Функция fork() в Perl используется для создания нового процесса.

В родительском процессе она возвращает PID дочернего процесса; в дочернем процессе она возвращает 0. Если возникает ошибка (например, недостаточно памяти), она возвращает undef и устанавливает $! в соответствующее сообщение об ошибке.

fork можно использовать вместе с exec. Функция exec завершает процесс после выполнения команды в кавычках.

Пример

#!/usr/bin/perl if(!defined($pid = fork())) { # fork возвращает undef при ошибке die "Не удалось создать дочерний процесс:$!"; }elsif ($pid == 0) { print "Вывод из дочернего процесса\n"; exec("date") || die "Не удалось вывести дату:$!"; } else { # В родительском процессе print "Вывод из родительского процесса\n"; $ret = waitpid($pid, 0); print "ID завершённого процесса:$ret\n"; } 1;

Выполните приведённую выше программу, вывод будет следующим:

通过父进程输出
通过子进程输出
2016年 6月19日 星期日 22时21分14秒 CST
完成的进程ID: 47117

Когда процесс завершается, он отправляет сигнал CHLD родительскому процессу, а затем становится зомби-процессом. Родительскому процессу нужно использовать wait и waitpid, чтобы завершить его. Конечно, вы также можете установить $SIG{CHLD} в IGNORE:

Пример

#!/usr/bin/perl local $SIG{CHLD} = "IGNORE"; if(!defined($pid = fork())) { # fork возвращает undef при ошибке die "Не удалось создать дочерний процесс:$!"; }elsif ($pid == 0) { print "Вывод из дочернего процесса\n"; exec("date") || die "Не удалось вывести дату:$!"; } else { # В родительском процессе print "Вывод из родительского процесса\n"; $ret = waitpid($pid, 0); print "ID завершённого процесса:$ret\n"; } 1;

Выполните приведённую выше программу, вывод будет следующим:

通过父进程输出
通过子进程输出
2016年 6月19日 星期日 22时30分56秒 CST
完成的进程ID: -1

Функция kill

Perl kill('signal', (Process List))Отправляет сигнал группе процессов. signal — это числовой сигнал для отправки; 9 убивает процесс.

Сначала рассмотрим распространённые сигналы в Linux, как показано в следующем списке:

信号名          值          标注          解释
————————————————————————————————————————————————————————————
HUP             1           A             检测到挂起
INT               2           A             来自键盘的中断
QUIT            3           A             来自键盘的停止
ILL               4           A             非法指令
ABRT          6           C             失败
FPE             8           C             浮点异常
KILL             9           AF            终端信号
USR1          10          A             用户定义的信号1
SEGV          11          C             非法内存访问
USR2          12          A             用户定义的信号2
PIPE           13          A             写往没有读取者的管道
ALRM         14          A             来自闹钟的定时器信号
TERM         15          A             终端信号
CHLD          17          B             子进程终止
CONT         18          E             如果被停止则继续
STOP         19          DF            停止进程
TSTP          20          D             tty键入的停止命令
TTIN            21          D             对后台进程的tty输入
TTOU          22          D             对后台进程的tty输出

Следующий пример отправляет сигнал SIGINT процессам 104 и 102:

Пример

#!/usr/bin/perl kill('INT', 104, 102); 1;
Другие расширения