Perl-プロセス管理

Perlをさまざまな方法で使用して、要件に応じて新しいプロセスを作成できます。このチュートリアルでは、Perlプロセスを作成および管理するためのいくつかの重要で最も頻繁に使用される方法をリストします。

  • 特別な変数を使用できます $$ または $PROCESS_ID 現在のプロセスIDを取得します。

  • 上記の方法のいずれかを使用して作成されたすべてのプロセスは、独自の仮想環境を維持します。 %ENV 変数。

  • ザ・ exit() 関数は常にこの関数を実行する子プロセスのみを終了し、実行中のすべての子プロセスが終了しない限り、メインプロセス全体は終了しません。

  • 開いているすべてのハンドルは子プロセスでdup()されているため、1つのプロセスでハンドルを閉じても、他のプロセスには影響しません。

バックスティックオペレーター

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
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などのシェル環境変数が含まれている場合は注意してください。次の3つのシナリオを試してください-

#!/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システムコールに対応する関数。fork()システムコールが利用可能なほとんどのUnixライクなプラットフォームでは、Perlのfork()は単にそれを呼び出します。fork()システムコールが利用できないWindowsなどの一部のプラットフォームでは、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()によって返される疑似プロセスIDとして渡すことができます。これらの呼び出しは、疑似プロセスの終了を適切に待機し、そのステータスを返します。あなたがあなたの子供を使用するのを待つことなくフォークした場合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()によって返されたIDを渡すことにより、疑似プロセスを終了できます。

疑似プロセスを実装するスレッドはリソースをクリーンアップする機会がないため、疑似プロセス()でkill( 'KILL'、(プロセスリスト))を使用すると、通常、メモリリークが発生する可能性があることに注意してください。

使用できます kill() 他のシグナルをターゲットプロセスに送信する関数。たとえば、次のようにSIGINTをプロセスID104および102に送信します。

#!/usr/bin/perl

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