- Perl 基础
- Perl - 首页
- Perl - 简介
- Perl - 环境
- Perl - 语法概述
- Perl - 数据类型
- Perl - 变量
- Perl - 标量
- Perl - 数组
- Perl - 哈希表
- Perl - IF...ELSE
- Perl - 循环
- Perl - 运算符
- Perl - 日期和时间
- Perl - 子程序
- Perl - 引用
- Perl - 格式
- Perl - 文件I/O
- Perl - 目录
- Perl - 错误处理
- Perl - 特殊变量
- Perl - 编码规范
- Perl - 正则表达式
- Perl - 发送邮件
- Perl 高级
- Perl - 套接字编程
- Perl - 面向对象
- Perl - 数据库访问
- Perl - CGI 编程
- Perl - 包和模块
- Perl - 进程管理
- Perl - 嵌入式文档
- Perl - 函数引用
- Perl 有用资源
- Perl - 问答
- Perl - 快速指南
- Perl - 有用资源
- Perl - 讨论
Perl - 进程管理
您可以使用 Perl 通过各种方式根据您的需求创建新进程。本教程将列出创建和管理 Perl 进程的一些重要且最常用的方法。
您可以使用特殊变量$$ 或 $PROCESS_ID 获取当前进程 ID。
使用任何上述方法创建的每个进程都维护其自身的虚拟环境,位于%ENV 变量内。
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 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
如果您的命令包含 shell 环境变量(如 $PATH 或 $HOME),请小心。尝试以下三种情况:
#!/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
fork() 函数
Perl 提供了一个fork() 函数,它对应于同名的 Unix 系统调用。在大多数可使用 fork() 系统调用的类 Unix 平台上,Perl 的 fork() 只会调用它。在某些平台(如 Windows)上,fork() 系统调用不可用,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 传递。这些调用将正确等待伪进程的终止并返回其状态。如果您使用 fork() 而从未使用 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', (进程列表)) 函数可用于通过向其传递 fork() 返回的 ID 来终止伪进程。
请注意,在伪进程上使用 kill('KILL', (进程列表)) 通常会导致内存泄漏,因为实现伪进程的线程没有机会清理其资源。
您可以使用kill() 函数向目标进程发送任何其他信号,例如,以下操作将向进程 ID 104 和 102 发送 SIGINT:
#!/usr/bin/perl kill('INT', 104, 102); 1;