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

Hi all, well, I have another question now after trying to go with wog's idea of forking off a child before starting up my mainwindow in for tk (on win32).

My goal: To have a forked child just sit there waiting for commands to come in and when one comes in, do it. The commands will just be web page urls to go get and dump in a file. Ideally then the child could send on a reverse pipe a command to the parent saying the page is done.

I went to the IPC help page on perldoc.com and here was my (sad?) attempt at getting a child to wait. Just to point out, I am getting parent and child to both work in the standard "bidirectional communication" example from perldoc.com but here I'm trying to add to that to make the child wait for a readable file handle. Any help would really be appreciated.

#!/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 :-( use IO::Select; # 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); $sel = new IO::Select( PARENT_RDR ); if ($pid = fork) { close PARENT_RDR; close PARENT_WTR; print CHILD_WTR "Parent Pid $$ is sending this\n"; chomp($line = <CHILD_RDR>); print "Parent Pid $$ just read this: `$line'\n"; close CHILD_RDR; close CHILD_WTR; waitpid($pid,0); } else { die "cannot fork: $!" unless defined $pid; close CHILD_RDR; close CHILD_WTR; print PARENT_WTR "Before: Child Pid $$ is sending this\n"; while(@ready = $sel->can_read) { foreach $fh (@ready) { chomp($line = <$fh>); print "Child Pid $$ just read this: `$line'\n"; } } print PARENT_WTR "After: Child Pid $$ is sending this\n"; close PARENT_RDR; close PARENT_WTR; exit; }

Justin Eltoft

"If at all god's gaze upon us falls, its with a mischievous grin, look at him" -- Dave Matthews

Replies are listed 'Best First'.
(tye)Re: IPC, trying for have child wait for commands
by tye (Sage) on Jun 05, 2001 at 22:29 UTC

    Win32 Perl doesn't have real fork so file handles are shared between the pseudo processes so close in one affects all of them.

    Try open2 or open3 instead.

            - tye (but my friends call me "Tye")
      Thanks for the help! One question about that though. This example, if you remove me trying to wait for the PARENT_RDR to be readable, works on my win32. If close were interferring, wouldn't this example straight from the ipc help not work?

      Thanks, Justin

        Hm, it appears that Win32 Perl's close also pretends. Oh well, your code is still using things that I've found very easy to break because they are just pretending (and are still pretty new).

        select will only work on TCP/IP sockets under Win32.

        If you are blocking until you are able to read, then just call read and let if block. Your code only has an advantage when you have more than pipe you wish to read from.

                - tye (but my friends call me "Tye")
      No, according to perlfork man page, "Any filehandles open at the time of the fork() will be dup()-ed. Thus, the files can be closed independently in the parent and child, but beware that the dup()-ed handles will still share the same seek pointer. Changing the seek position in the parent will change it in the child and vice-versa. One can avoid this by opening files that need distinct seek pointers separately in the child."
Re: IPC, trying for have child wait for commands
by Eradicatore (Monk) on Jun 06, 2001 at 21:32 UTC
    Just an update, I figured out what I wanted last night. Here is the code: