iic has asked for the wisdom of the Perl Monks concerning the following question:

These codes can run on Linux,but can not on NT with
activerperl5.6(no error reported).why?Thank you.

#!/usr/bin/perl
use FileHandle;
STDOUT->autoflush;
$sum=0;
while(1)
{
$sum++;
print "Round $sum:input a name\n";
chomp($name=<>);
$read="READ$name";
$write="WRITE$name";
pipe($read,$write);
$write->autoflush();
if(!($pid=fork))
{
close($write);
$read->autoflush();
while($content=<$read>){print "(I'm $name)Parent said:$content"}
close($read);
exit;
}
if(!defined($pid)){print "ERROR\n";exit;}
close($read);
$children{$name}=$write;
foreach $key (keys %children)
{
$it=$children{$key};
print $it "father's test\n";
}
sleep 1;
}

Replies are listed 'Best First'.
Re: why?
by chromatic (Archbishop) on May 04, 2000 at 21:18 UTC
    Piping can be a gotcha on NT, though it seems to have more issues with file associations.

    Running things under strict and -w make me wonder about the lines:

    my $read="READ$name"; my $write="WRITE$name"; pipe($read,$write);
    You're using symbolic references here, as pipe expects filehandles to connect together. Create the handles explicitly (with the open command) and try it. You might also enable warnings as I did, to see if the parser gives you better errors. (I think you need to create FileHandle objects for $read and $write.)
      I have tried using IO::Pipe to create pipe and using IO::Select to wait for the pipe before I posted. But... Thank you.
Re: why?
by buzzcutbuddha (Chaplain) on May 04, 2000 at 16:29 UTC
    I can't say for sure why it is not working. I downloaded it, and
    ran it, and it hangs in NT...my feeling would be that it's a quirk
    with how Fork is implemented on NT. This is a new feature in 5.6, and
    I am almost certain that it will behave differently than Unix Fork.
    The PerlFork documentation has not been updated for 5.6 yet....
    Have you tried running your code on the NT box with the debug option?
      Yes,I have the same feeling with you that fork() in
      activeperl (NT) does not work as the rule we have known.
      I have tried that script step by step.It stop at the second
      time to execute the function fork().
      It seems to can not to fork() again when there is a
      child process in existence and the child is waiting for a
      filehandle.
      It's all that I have found so far.
      Sorry,English is not my native language.Hope you can
      understand my "English" : ).
      Whatsoever,many thanks for your answer.
open fork in Win32
by JeffyPop (Initiate) on May 05, 2000 at 05:10 UTC
    I'm trying to do open( STDOUT, "|-" ); with perl 5.004 on winNT. I don't think you can fork in WinNT, so is there an alternative for postprocessing your own output?
Re: why?
by chromatic (Archbishop) on May 05, 2000 at 06:23 UTC
    Here's code adapted from the Cookbook that may do what you want:
    use IO::Handle; pipe(READER, WRITER); WRITER->autoflush(1); if ($pid = fork) { # if fork returned a PID, this must be the parent close READER; # so the child can use it print WRITER "Your message here, call 555-8467, extension $$!"; close WRITER; waitpid($pid, 0); # let the kid die } else { # if $pid is empty, this must be the child close WRITER; # so the parent can use it my $line = <READER>; print "What does this mean?\n\t>>$line<<\n"; close READER; # don't have to be explicit exit; }
    The close() is important because fork tends to duplicate open filehandles between the parent and child. We take advantage of some of this, though.

    I don't know how well it will work passing variables instead of explicit filehandle names to the pipe call. You might have better results with:

    local *$read; local *$write;
      Well,I think you didn't know my meaning. I don't suspect fork() and pipe() can run well on activeperl (package 613). My trouble is parent can not have two children at the same time and one of the children are waiting for a filehandle! Thanks.
        Oh, I see what you mean now.

        Forking works fine on ActivePerl 613 on NT, at least for me. The trouble is with the program flow. The first time through, you connect the parent's filehandles together. Fine. Then you fork off a child, let it keep the reader (and the parent the writer) and you send a message from parent to child. Child displays it, receives the EOF, and then exits. Perl closes the reader implicitly. The second time through, the parent uses pipe again, making another child. It then iterates through a hash of children, trying to send them messages.

        Unfortunately, the other end of the pipe connected to the first child is gone. That'll cause some trouble.

        Either close the writer at the end of the loop, or keep your children alive.