讲解:
无参数;
当本进程为父进程时返回值为子进程的PID值,当进程为子进程时返回值为0。
实例:
#!usr/bin/perl -w $pid=fork(); #复制进程,并把返回值附入$pid die "Error:$!\n" unless defined $pid; #制定程序的错误机制,此步可略 if$pid!=0{ #条件选择,测试$pid值,以确定为子进程还是父进程 print"This is a main pid!PID is $$!\n"; #$pid值不等于0,此为父进程(附:$$为保留变量,其值为此进程的PID) }else{ #否则.. print"This is a sub pid!PID is $$!\n"; #$pid值为0,此为子进程 } exit 1;
|
分析实例:
楼上的程序没有父进程与子进程的明显分化,要将它们分开就要靠测试$pid的值,所以对
fork()函数的
调用来说条件语句是非常重要的,需要通过它们来辨别
fork()的返回值。
Does a fork(2) system call to create a new process running the same program at the same point.
fork以后,子进程从fork点开始和主进程运行相同的程序,所以可以通过测试$pid来使主进程和子进程运行不同的程序,
子进程所做的工作结束后应该退出
,不然会继续运行if代码块以后的父进程的程序,这样会运行两次父进程的程序。
fork,It clo
nes off a duplicate process identical in virtually every aspect to its parent,
including variable settings and open files.(《perl cookbook》)
!
/usr/bin/perl
-w
my $pid
= fork
; if $pid
= 0
) {
print
"is parent\n"; }
else {
#
this is the child process
print
"is child\n"; #子进程退出,会继续运行if一下的程序。 }
print
'program after "if"'."\n" #会打印两次,一次是父进程打印,一次是子进程打印的。
; exit 0; #子进程退出,不会运行if以后的程序 }
print "\n" #只有父进程打印一次
|
pipe():创建管道对。
格式: pipe(READ,WRITE);
The pipe function creates two connected filehandles,a reader and writer,whereby anything written to the writer can be read from the reader.(摘自《perl cookbook》)
pipe创建两个连接的句柄,
一个读,
一个写,任何写入到writer的都可以从reader中读出。
实 例:pipe(README,WRITEME); #创建了
一个管道对,"README"用于读,"WRITEME"用于写。
$aaa=pipe(AAA,BBB); #创建了
一个管道对,"AAA"用于读,"BBB"用于写,$aaa变量为
调用pipe()的返回值。
讲解:正常
调用后返回值为非零数,第
一个参数为被创建的读管道,第二个参数为被创建的写管道。此
函数通常配合进程中 的
fork()函数一同使用,步骤是先使用pipe()函 数建立管道对,再使用
fork()创建新进程,在不同的进程
关闭不同的管道,这样就可以达到管道间通信的目的了。
格式: close(AAA);
close BBB;
讲 解:close()在
调用时能将子程序的终止
代码放到特殊变量$?中;当
关闭的是写管道时close()
调用将进入堵塞状态直至另一端完成它的 全部工作为止。
子进程通过父进程获得输入
-w my $uid ="test 123";
pipe(CHILD_RDR, PARENT_WTR; my $pid ; $pid != 0) { #this is parent process close CHILD_RDR; print PARENT_WTR "$uid"; } else { # this is the child process close PARENT_WTR; $u = <CHILD_RDR>; print $u;
} |
父进程通过子进程获得输入
(PARENT_RDR; my $pid == 0this is child process close PARENT_RDR; print CHILD_WTR this is the parent process close CHILD_WTR<PARENT_RDR;
}
|
子进程和父进程双向通信:
#!/usr/bin/perl -w
# pipe1 - bidirectional communication using two pipe pa
irs
# designed for the socketpair-challenged
use IO::Handle; # thousands of li
nes just for autoflush :-(
pipe(PARENT_RDR,CHILD_WTR); # XXX: failure?
pipe(CHILD_RDR,PARENT_WTR); # XXX: failure?
CHILD_WTR->autoflush(1);
PARENT_WTR->autoflush(1);
if ($pid = fork) {
#this is parent process
close PARENT_RDR; close PARENT_WTR;
print CHILD_WTR "Parent Pid $$ is sending this\n";
chomp($line = <CHILD_RDR>);
print "Parent Pid $$ just read this: `$line'\n";
close CHILD_RDR; close CHILD_WTR;
waitpid($pid,0);
}
else
{
#this is child process
die "cannot fork: $!" unless defined $pid;
close CHILD_RDR; close CHILD_WTR;
chomp($line = <PARENT_RDR>);
print "Child Pid $$ just read this: `$line'\n";
print PARENT_WTR "Child Pid $$ is sending this\n";
close PARENT_RDR; close PARENT_WTR;
exit;
}
改进版:
#!/usr/bin/perl -w # pipe6 - bidirectional communication using socketpair # "the best ones always go both ways" use Socket; use IO::Handle; # We say AF_UNIX because although *_LOCAL is the # POSIX 1003.1g form of the constant, many machines # still don't have it. socketpair($child, $parent, AF_UNIX, SOCK_STREAM, PF_UNSPEC) or die "socketpair: $!"; $child->autoflush(1); $parent->autoflush(1); if ($pid = fork) { close $parent; print $child "Parent Pid $$ is sending this\n"; chomp($line = <$child>); print "Parent Pid $$ just read this: '$line'\n"; close $child; waitpid($pid,0); } else { die "cannot fork: $!" unless defined $pid; close $child; chomp($line = <$parent>); print |