进程管理
1. 简介
有两种实现“并发”的主要方法。一种是使每个任务在完全独立的内存空间内运行。也就是说,他们中的每一个都拥有用于执行任务的独立内存区域,这就是进程。另一种是有两个同时执行的任务,也就是执行线程,他们在同一内存空间内运行。这就是所谓的多线程。创建一个线程比创建一个进程更有效率,但代价是:县城更加危险。使用进程可以避免在其他进程不知道的情况下,某个进程擅自对共享数据进行处理。这种问题被称作“RaceCondition”,它需要依赖线程建复杂的计时机制。
2. fork命令
要想创建一个新进程,一个最简单的方法就是使用fork函数。当调用fork函数时,他如果不是调用系统的fork函数(如果系统存在)来创建一个新的进程,就是通过复制解释器来模仿它。从这个进程产生的任何进程称为子进程。每个进程有一个唯一的进程号,即pid。当调用fork函数时,如果调用成功,就会创建一个等同于父进程的子进程,该子进程继承了父进程的所有属性,比如环境变量。两个进程间的唯一差别在于fork调用的返回值。在子进程中,他返回0;而在父进程中,他返回子进程的编号。如果fork调用不成功,会返回undef。这样可以用if语句来判别哪个进程正在执行,并执行特定进程的步骤。程序运行时,独立进程将共享处理器时间。
注意:Perl5.6版本以前的win32版本中,fork不可用。
特殊变量$| (亦即$OUTPUT_AUTOFLUSH)设置为1。如果这个变量有一个非零值,那么当print和write语句执行时,所选择的输出通道会自动的刷新。当两个或更多的进程输出到同一个文件句柄,且输出应该准确地反映每个print或write的发生时间时,这就非常重要。当$|变量设为假值,输出将有时不能反映输出实际发生的顺序。
wait函数在允许父进程继续执行前,必须等待所有子进程结束运行。该函数返回结束运行的子进程进程编号,或在没有子进程时返回-1。
if ( ( $pid1 = fork() ) && ( $pid2 = fork() ) ) {
print ( “I have to wait for my kids. /n” );
my $straggle = wait();
print ( “Finally $straggle finished,now I can go. /n” );
}
elsif ( $pid1 && difined ( $pid2 ) ) {
sleep (2);
print ( “Kid2: So is min … /n”);
sleep (4);
exit ();
}
elsif ( difined ( $pid1 ) ) {
sleep (1);
print ( “Kid1: My parent is patient … /n”);
sleep (2);
}
else {
die ( “Forking problem: ” );
}
这段程序创建了两个子进程,两次使用函数fork。
不要使用$PID(变量名为大写),因为它是一个特殊变量,他是运行程序本身的进程编号,等同于特殊变量$PROCESS_ID和 $$。
如果要等待一个特定的进程结束,可以使用waitpid函数,他把进程编号作为第一个参数使用。他会等进程结束运行,然后返回这个进程的进程编号。如果没有子进程返回进程编号或该子进程已死,则waitpid返回-1。子进程退出状态保存在特殊变量$?中。
3. system和exec函数
在程序外部执行其他程序有两种方式。最简单的是调用函数exec,他使用shell命令来唤醒声明为参数的程序,然后用刚启动的程序来替代当前进程。这样,新启动的进程结束时,当前进程结束。
shell处理执行作为第一个参数传递给exec的命令,所有的通配符在这里依然有效。这样shell将处理通配符表达式(如:dir *.exe)、管道操作(如:dir * | more<SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family:
<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>