Perl 프로세스 관리


Perl에서는 다양한 방식으로 프로세스를 생성할 수 있습니다.

이 튜토리얼에서는 몇 가지 프로세스 관리 방법에 대해 설명합니다.

  • 특수 변수 $$ 또는 $PROCESS_ID를 사용하여 프로세스 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 명령을 실행하면 결과가 직접 출력됩니다. 기본적으로 Perl의 STDOUT이 현재 가리키는 곳, 즉 일반적으로 화면으로 전송됩니다. 리디렉션 연산자>를 사용하여 지정된 파일로 출력할 수도 있습니다.

위 프로그램을 실행하면 출력 결과는 다음과 같습니다.

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 作为 shell 环境变量
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() 함수

Perl fork() 함수는 새로운 프로세스를 생성하는 데 사용됩니다.

부모 프로세스에서는 자식 프로세스의 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}를 IGNORG로 설정할 수도 있습니다.

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

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输出

다음 예에서는 프로세스 104 및 102에 SIGINT 신호를 보냅니다.

#!/usr/bin/perl

kill('INT', 104, 102);
 
1;