加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Perl 使用管道实现进程间的通信

发布时间:2020-12-16 00:07:59 所属栏目:大数据 来源:网络整理
导读:fork()函数:? 作用:进程复制函数。? 用法:$pid=fork(); ? ? 讲解:? 无参数; 当本进程为父进程时返回值为子进程的PID值,当进程为子进程时返回值为0。 ? 实例:? # ! usr/bin/perl? - w? $pid = fork ( ) ; ? #复制进程,并把返回值附入$pid? die? "Error:$!
fork()函数:?
作用:进程复制函数。?
用法:$pid=fork(); ? ?
讲解:?
无参数; 当本进程为父进程时返回值为子进程的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()的返回值。?

注: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 clones 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 parentn";
????????}?else?{
????????????????#?this?is the child process
????????????????print?"is childn"; ?#子进程退出,会继续运行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(): 关闭管道?
格式: 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;?

}




子进程和父进程双向通信:
http://perldoc.perl.org/perlipc.html#Bidirectional-Communication-with-Yourself
#!/usr/bin/perl -w?
# pipe1 - bidirectional communication using two pipe pairs?
# ? ? ? ? designed for the socketpair-challenged?
use IO::Handle; # thousands of lines 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 thisn";?
? 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 thisn";?
? 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 thisn";
??????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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

相关内容
推荐文章
站长推荐
热点阅读