top
Loading...
Perl 進程管理

Perl 進程管理

Perl 中你可以以不同的方法來創建進程。

本教程將討論一些進程的管理方法。

  • 你可以使用特殊變量 $$$PROCESS_ID 來獲取進程 ID。

  • %ENV 哈希存放了父進程,也就是shell中的環境變量,在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 函數

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;
北斗有巢氏 有巢氏北斗