Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

getting data out of fork()s

Status
Not open for further replies.

Ardeaem

Programmer
Feb 8, 2002
4
US
I have the code below. As you can see, in the child processes, I'd like to
have data pushed onto an array (@test). However, nothing ever gets pushed.
I've tried push, I've tried setting $test[$x]=time; I've tried using
scalars, I just can't get any data out of the fork()ed processes.

What's going on? How can I get info from them?

Thanks,
Richard Morey


#!/usr/bin/perl


use LWP::Simple;
@URLs=(" " "" "
@test=();

# start 5 processes
for ($x=0;$x<=$#URLs;$x++)
{
&start_a_child;
}

# wait for the processed to finish
while (!$endloop)
{
$pid = wait; # wait on a child process to exit

print &quot;Process number $pid just finished.\n&quot;;
$endloop=1 if ($pid==-1);

}

print &quot;Program ended successfully.&quot;;


sub do_something
{
print &quot;I am process number $$ and I am about to&quot;
. &quot; do something.\n&quot;;

$info=(get $URLs[$x]);

print &quot;And now process number $$ ($URLs[$x]) is done.\n&quot;;
}

sub start_a_child
{
$pid = fork;

die &quot;Can't fork ($!)\n&quot; unless defined $pid;

if (not $pid)
{
&do_something;
push(@test, time);
exit;
}
}
 
Richard, hi.

I think you need to look again at what the fork() system call does.

Let's say you have a Perl script with an array in it, as you do above.

When you call fork() your script will take a copy of itself, so you then have two running scripts, each with its own array.

You can't use that array to pass data between child and parent processes - or between children - because each script has its own copy of that array - the array is not shared after a fork().

If you need to pass data between processes like that you need another method. The simplest way would be to use a file. Next simplest would be to use a named pipe (a fifo), assuming you're on UNIX, and then TCP sockets. Both of these give you a one-way pipe into another application.

Hope that this is helpful and that I haven't explained something you already know.

Regards, Mike
michael.j.lacey@ntlworld.com
Email welcome if you're in a hurry or something -- but post in tek-tips as well please, and I will post my reply here as well.
 
Thanks for your reply. I found this shortly after my post, and attempted to implement a pipe. As you can see, in the code above, there would be multiple forks writing to the pipe (wich the parent listening). There only seems to be one fork (the first) getting through. After the wait block,
I used
while(<INPUT>){
$info=$info.$_; #I want it intact
}

And I only get the first fork's info. Why?
Thanks fot your help.
 
I think a file would be the best method of allowing multiple child processes to communicate with the parent.

You could use flock() to lock the file and make sure that only one child process writes to the file at once.

In your parent process, open the file to read the data from the child processes, and then wait for data to arrive in the file like this:
[tt]
while(){
while(<F>){
# read some data
}
if(all_children_have_reported){
last; # exit loop
}
sleep(1); # end of file found, wait for a bit
seek(F,0,1); # reset the file position,
# new data will be visible
}
[/tt]

Mike
michael.j.lacey@ntlworld.com
Email welcome if you're in a hurry or something -- but post in tek-tips as well please, and I will post my reply here as well.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top