代码之家  ›  专栏  ›  技术社区  ›  Avinash

Perl管道和C进程作为子进程[Windows]

  •  1
  • Avinash  · 技术社区  · 14 年前

    我想分叉一个子进程(它是我的C可执行文件)并在perl和C进程之间共享一个管道, 是否可以将STDOUT和STDIN用作管道。

    尝试使用以下代码,但子进程继续运行。

    use IPC::Open2;
    use Symbol;
    my $CHILDPROCESS= "chile.exe";
    $WRITER = gensym();
    $READER = gensym();
    
    my $pid = open2($READER,$WRITER,$CHILDPROCESS);
    while(<STDIN>)
    {
       print $WRITER $_;
    }
    close($WRITER);
    while(<$READER>)
    {
        print STDOUT "$_";
    }
    
    3 回复  |  直到 14 年前
        1
  •  1
  •   Greg Bacon    14 年前

    这个 Safe Pipe Opens perlipc文档的一节描述了一个很好的特性:

    这个 open 函数将接受 "-|" "|-" 做一件非常有趣的事情:它分叉一个连接到您打开的文件句柄的子对象。子程序与父程序运行相同的程序。例如,这对于在假定的UID或GID下运行时安全地打开文件非常有用。如果你打开一个管道到负,你可以写你打开的文件句柄,你的孩子会发现它在他的 STDIN . 如果你从负开始打开一个管道,你可以从文件句柄中读取你打开的孩子写给他的任何东西 STDOUT .

    但是根据 perlport documentation

    打开

    开放给 |- -| 不受支持。(Win32,RISC操作系统)

        2
  •  0
  •   KLee1    14 年前

    编辑:这可能只适用于Linux。我还没有试过用在窗户上。不过,可能有一种方法可以在Windows中模拟它。

    我想这是你想要的:

    #Set up pipes to talk to the shell.
    pipe(FROM_PERL, TO_C) or die "pipe: $!\n";
    pipe(FROM_C, TO_PERL) or die "pipe: $!\n";
    
    #auto flush so we don't have (some) problems with deadlocks.
    TO_C->autoflush(1);
    TO_PERL->autoflush(1);
    
    if($pid = fork()){
        #parent
        close(FROM_PERL) or die "close: $!\n";
        close(TO_PERL) or die "close: $!\n";
    }
    else{
        #child
        die "Error on fork.\n" unless defined($pid);
    
        #redirect I/O
        open STDIN, "<&FROM_PERL";
        open STDOUT, ">&TO_PERL";
        open STDERR, ">&TO_PERL";
        close(TO_C) or die "close: $!\n";
        close(FROM_C) or die "close $!\n";
    
        exec("./cprogram"); #start program
    }
    

    现在,您可以通过FROM_C和to_C分别作为输入和输出与shell通信。

        3
  •  0
  •   tchrist    14 年前

    本问答结束 Perlmonks 表明 open2 在Windows上运行良好,前提是你足够小心地管理它。