繁体   English   中英

派生时Windows上Perl中STDOUT的IO句柄?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM