
[英]Perl using `IO::Handle` or `IO::File` when not reading actual files
[英]IO handle for STDOUT in Perl on Windows when forking?
我有以下问题:我尝试将perl脚本移植到Windows。 该脚本经常分叉自身,并使用以下代码进行分叉:
sub sub_fork {
my ( $subref, @args ) = @_;
my $fh = new IO::Handle;
my $pid = open( $fh, "-|" );
if ( $pid ) { # parent
return ( $fh, $pid );
}
else {
&$subref( @args );
exit;
}
}
Windows不喜欢“-|” 它似乎。 我实际上不知道这是做什么的,作为Windows的家伙,但是这里有一些有趣的东西: http : //www.cs.tufts.edu/comp/150PPP/notes/perl_ipc.php (搜索“ Fancy “)该代码在脚本中经常使用,因此我想用一个工作原理完全相同的子替换它,这意味着它返回$ fh,$ pid,其中$ fh是该子stdout的句柄。
此构造用于进程间通信 ,特别是创建从新后台进程的标准输出读取的文件句柄。
my $pid = open my $fh, "-|";
if ($pid == 0) { # child
print "Hello world\n";
exit;
}
print <$fh>; # Hello world\n
出于某些原因,请参阅perlipc
doc,以了解该构造有用的原因。
但是,这仅适用于带有“ true fork”的系统,但不包括Windows。 一个Windows解决办法将涉及使用socketpair
创建IPC一些插座( pipe
,唉,是不是达到在Windows任务要么)。 这样的事情会起作用:
sub sub_fork {
my ($subref, @args) = @_;
use Socket;
my ($READER, $WRITER);
socketpair $READER, $WRITER, AF_UNIX, SOCK_STREAM, PF_UNSPEC;
shutdown($READER,1); # close write channel for $READER
shutdown($WRITER,0); # and read channel for $WRITER
my $pid = fork();
if ( $pid ) {
return ($READER, $pid);
} else {
close STDOUT;
open STDOUT, '>&' . fileno($WRITER); # dup STDOUT to print to $WRITER
&$subref(@args);
# both of these steps are required before you exit the child
close STDOUT;
shutdown($WRITER,1);
exit;
}
}
我编写的Forks::Super
模块也可以在Windows中解决此任务。
use Forks::Super;
sub sub_fork {
my ($subref, @args) = @_;
my $pid = fork { child_fh => 'out' }; # make child's STDOUT available
if ($pid != 0) {
return ($Forks::Super::CHILD_STDOUT{$pid}, $pid);
#alternate: return ($pid->{child_stdout}, $pid);
} else {
&$subref(@args);
exit;
}
}
甚至更简洁
use Forks::Super;
sub sub_fork {
my ($subref, @args) = @_;
my $pid = fork {
child_fh => 'out',
sub => $subref, args => \@args # run $subref->(@args) in child
};
return ($Forks::Super::CHILD_STDOUT{$pid}, $pid);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.