您可以通过各种方式使用Perl根据您的要求创建新流程.本教程将列出几个重要且最常用的创建和管理Perl进程的方法.
您可以使用特殊变量 $$ 或 $ PROCESS_ID 获取当前进程ID.
使用任何进程创建的每个进程提到的方法,用in-in %ENV 变量维护自己的虚拟环境.
exit()函数总是退出执行此函数的子进程,除非所有正在运行的子进程都已退出,否则整个主进程不会退出.
全部在子进程中打开句柄是dup() - 所以在一个进程中关闭任何句柄不会影响其他句柄.
执行任何Unix命令的最简单方法是使用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()函数执行任何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等shell环境变量时要小心.尝试以下三种方案 :
#!/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;
当执行上面的代码时,它会产生以下结果,具体取决于shell变量$ 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
Perl提供了一个 fork()函数,它对应于同名的Unix系统调用.在大多数类似于Unix的平台上,fork()系统调用可用,Perl的fork()只是调用它.在某些平台上,例如没有fork()系统调用的Windows,可以构建Perl以在解释器级别模拟fork().
fork()函数用于克隆当前进程.此调用创建一个在同一点运行相同程序的新进程.它将子pid返回到父进程,0返回子进程,如果fork不成功则返回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
Perl kill('KILL',(进程列表))函数可用于终止伪通过传递fork()返回的ID来处理它.
注意在伪进程()上使用kill('KILL',(进程列表))通常可能导致内存泄漏,因为实现伪进程的线程没有机会清理其资源.
你可以使用 kill()函数发送任何其他信号目标进程,例如以下将SIGINT发送到进程ID 104和102 :
#!/usr/bin/perl kill('INT', 104, 102); 1;