How to resolve funky sync issues with fork here. - Unix
This is a discussion on How to resolve funky sync issues with fork here. - Unix ; Here is a copy a persons code I saw on a blog. The only difference
here is that I enable warnings use my().
#!/usr/bin/perl -w
my @array = qw(ugh geeze blah test smith bob homes point);
my $num = "10";
...
-
How to resolve funky sync issues with fork here.
Here is a copy a persons code I saw on a blog. The only difference
here is that I enable warnings use my().
#!/usr/bin/perl -w
my @array = qw(ugh geeze blah test smith bob homes point);
my $num = "10";
for(1..$num) {
my $pid = fork();
if ($pid) {
# parent
push(@childs, $pid);
} elsif ($pid == 0) {
# child
print "@array\n\n";
sleep 5;
exit(0);
} else {
die "couldn't fork: $!\n";
}
print "BEFORE FOR BRACKET\n";
}
print "AFTER FOR BRACKET\n";
foreach (@childs) {
waitpid($_, 0);
}
And here is what I get when I run it a few times...
[cdalten@localhost perl]$ ./par.pl
ugh geeze blah test smith bob homes point
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
BEFORE FOR BRACKET
AFTER FOR BRACKET
[cdalten@localhost perl]$ ./par.pl
ugh geeze blah test smith bob homes point
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
BEFORE FOR BRACKET
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
ugh geeze blah test smith bob homes point
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
BEFORE FOR BRACKET
AFTER FOR BRACKET
[cdalten@localhost perl]$
The lines:
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
Sometmes don't appear in sync. How would I get them in sync? Would I
have to insert another wait() into the child? Just need some ideas
here.
Chad
-
Re: How to resolve funky sync issues with fork here.
["Followup-To:" header set to comp.lang.perl.misc.]
grocery_stocker wrote:
> Sometmes don't appear in sync. How would I get them in sync?
$| = 1;
> Just need some ideas
> here.
Suffering from Buffering?
http://perl.plover.com/FAQs/Buffering.html
--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas
-
Re: How to resolve funky sync issues with fork here.
On Apr 3, 9:27 pm, "grocery_stocker" wrote:
> Here is a copy a persons code I saw on a blog. The only difference
> here is that I enable warnings use my().
>
> #!/usr/bin/perl -w
>
> my @array = qw(ugh geeze blah test smith bob homes point);
>
> my $num = "10";
>
> for(1..$num) {
> my $pid = fork();
> if ($pid) {
> # parent
> push(@childs, $pid);
> } elsif ($pid == 0) {
> # child
> print "@array\n\n";
> sleep 5;
> exit(0);
> } else {
> die "couldn't fork: $!\n";
> }
> print "BEFORE FOR BRACKET\n";
>
> }
>
> print "AFTER FOR BRACKET\n";
>
> foreach (@childs) {
> waitpid($_, 0);
>
> }
>
> And here is what I get when I run it a few times...
[snip]
> [cdalten@localhost perl]$ ./par.pl
> ugh geeze blah test smith bob homes point
>
> BEFORE FOR BRACKET
> ugh geeze blah test smith bob homes point
>
> BEFORE FOR BRACKET
> ugh geeze blah test smith bob homes point
>
> BEFORE FOR BRACKET
> ugh geeze blah test smith bob homes point
>
> BEFORE FOR BRACKET
> ugh geeze blah test smith bob homes point
>
> BEFORE FOR BRACKET
> BEFORE FOR BRACKET
> ugh geeze blah test smith bob homes point
>
> ugh geeze blah test smith bob homes point
I presume that the above apparent out-of-order results is what you are
concerned about?
> BEFORE FOR BRACKET
> ugh geeze blah test smith bob homes point
>
> BEFORE FOR BRACKET
> ugh geeze blah test smith bob homes point
>
> BEFORE FOR BRACKET
> ugh geeze blah test smith bob homes point
>
> BEFORE FOR BRACKET
> AFTER FOR BRACKET
> [cdalten@localhost perl]$
>
> The lines:
> BEFORE FOR BRACKET
> ugh geeze blah test smith bob homes point
>
> Sometmes don't appear in sync.
Scheduling of ready processes is rarely so simple as to natively
produce an "in sync" result unless you've coded a tight coupling
between the processes. I'd say that there is no real problem here; you
just caught a couple of processes executing in an order that, while
legal and proper, you didn't expect.
> How would I get them in sync?
> Would I have to insert another wait() into the child? Just need some ideas
> here.
Move your waitpid() call so that it executes immediately prior to
your
print "BEFORE FOR BRACKET\n";
statement. This way, the parent will wait for the child to complete
(and thus write the array) before it proceeds to generate the BEFORE
FOR BRACKET line. In this way, you maintain a tight coupling between
parent process and child process.
-
Re: How to resolve funky sync issues with fork here.
On Apr 4, 5:22 am, "Lew Pitcher" wrote:
> On Apr 3, 9:27 pm, "grocery_stocker" wrote:
>
>
>
> > Here is a copy a persons code I saw on a blog. The only difference
> > here is that I enable warnings use my().
>
> > #!/usr/bin/perl -w
>
> > my @array = qw(ugh geeze blah test smith bob homes point);
>
> > my $num = "10";
>
> > for(1..$num) {
> > my $pid = fork();
> > if ($pid) {
> > # parent
> > push(@childs, $pid);
> > } elsif ($pid == 0) {
> > # child
> > print "@array\n\n";
> > sleep 5;
> > exit(0);
> > } else {
> > die "couldn't fork: $!\n";
> > }
> > print "BEFORE FOR BRACKET\n";
>
> > }
>
> > print "AFTER FOR BRACKET\n";
>
> > foreach (@childs) {
> > waitpid($_, 0);
>
> > }
>
> > And here is what I get when I run it a few times...
> [snip]
> > [cdalten@localhost perl]$ ./par.pl
> > ugh geeze blah test smith bob homes point
>
> > BEFORE FOR BRACKET
> > ugh geeze blah test smith bob homes point
>
> > BEFORE FOR BRACKET
> > ugh geeze blah test smith bob homes point
>
> > BEFORE FOR BRACKET
> > ugh geeze blah test smith bob homes point
>
> > BEFORE FOR BRACKET
> > ugh geeze blah test smith bob homes point
>
> > BEFORE FOR BRACKET
> > BEFORE FOR BRACKET
> > ugh geeze blah test smith bob homes point
>
> > ugh geeze blah test smith bob homes point
>
> I presume that the above apparent out-of-order results is what you are
> concerned about?
>
Yes, I'm concerned about the out-of-order-results.
>
> > BEFORE FOR BRACKET
> > ugh geeze blah test smith bob homes point
>
> > BEFORE FOR BRACKET
> > ugh geeze blah test smith bob homes point
>
> > BEFORE FOR BRACKET
> > ugh geeze blah test smith bob homes point
>
> > BEFORE FOR BRACKET
> > AFTER FOR BRACKET
> > [cdalten@localhost perl]$
>
> > The lines:
> > BEFORE FOR BRACKET
> > ugh geeze blah test smith bob homes point
>
> > Sometmes don't appear in sync.
>
> Scheduling of ready processes is rarely so simple as to natively
> produce an "in sync" result unless you've coded a tight coupling
> between the processes. I'd say that there is no real problem here; you
> just caught a couple of processes executing in an order that, while
> legal and proper, you didn't expect.
>
> > How would I get them in sync?
> > Would I have to insert another wait() into the child? Just need some ideas
> > here.
>
> Move your waitpid() call so that it executes immediately prior to
> your
> print "BEFORE FOR BRACKET\n";
> statement. This way, the parent will wait for the child to complete
> (and thus write the array) before it proceeds to generate the BEFORE
> FOR BRACKET line. In this way, you maintain a tight coupling between
> parent process and child process.
I moved the waipid() right before:
print "BEFORE FOR BRACKET\n";
And when I ran the program a a few hundred times. I got the tight
coupling. Now, for whatever reasons, I thought the sleep() in the
child process would somehow produce the tight coupling.
One last question. How can I tell if this program is running
sequentially or in parallel? I tried tracing the code via the
debugger, but all I got where like 10 screens when I ran the code.
Thanks,
Chad
-
Re: How to resolve funky sync issues with fork here.
"grocery_stocker" wrote:
>
> The lines:
> BEFORE FOR BRACKET
> ugh geeze blah test smith bob homes point
>
> Sometmes don't appear in sync. How would I get them in sync?
If you want to run things in sync, then don't fork. You seem to have a
X-Y problem here.
> Would I
> have to insert another wait() into the child? Just need some ideas
> here.
The child has nothing to "wait" for.
Xho
--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
-
Re: How to resolve funky sync issues with fork here.
["Followup-To:" header set to comp.lang.perl.misc.]
On 2007-04-04 12:22, Lew Pitcher wrote:
> On Apr 3, 9:27 pm, "grocery_stocker" wrote:
>> Here is a copy a persons code I saw on a blog. The only difference
>> here is that I enable warnings use my().
>>
>> #!/usr/bin/perl -w
>>
>> my @array = qw(ugh geeze blah test smith bob homes point);
>>
>> my $num = "10";
>>
>> for(1..$num) {
>> my $pid = fork();
>> if ($pid) {
>> # parent
>> push(@childs, $pid);
>> } elsif ($pid == 0) {
>> # child
>> print "@array\n\n";
>> sleep 5;
>> exit(0);
>> } else {
>> die "couldn't fork: $!\n";
>> }
>> print "BEFORE FOR BRACKET\n";
>>
>> }
>>
>> print "AFTER FOR BRACKET\n";
>>
>> foreach (@childs) {
>> waitpid($_, 0);
>>
>> }
>>
>> And here is what I get when I run it a few times...
> [snip]
>> [cdalten@localhost perl]$ ./par.pl
[...]
>> BEFORE FOR BRACKET
>> BEFORE FOR BRACKET
>> ugh geeze blah test smith bob homes point
>>
>> ugh geeze blah test smith bob homes point
>
> I presume that the above apparent out-of-order results is what you are
> concerned about?
[...]
>> How would I get them in sync?
>> Would I have to insert another wait() into the child? Just need some ideas
>> here.
>
> Move your waitpid() call so that it executes immediately prior to
> your
> print "BEFORE FOR BRACKET\n";
> statement. This way, the parent will wait for the child to complete
> (and thus write the array) before it proceeds to generate the BEFORE
> FOR BRACKET line.
If you do that, what's the point of forking in the first place?
hp
--
_ | Peter J. Holzer | Blaming Perl for the inability of programmers
|_|_) | Sysadmin WSR | to write clearly is like blaming English for
| | | hjp@hjp.at | the circumlocutions of bureaucrats.
__/ | http://www.hjp.at/ | -- Charlton Wilbur in clpm
-
Re: How to resolve funky sync issues with fork here.
On Apr 5, 6:05 am, "Peter J. Holzer" wrote:
> ["Followup-To:" header set to comp.lang.perl.misc.]
> On 2007-04-04 12:22, Lew Pitcher wrote:
>
>
>
> > On Apr 3, 9:27 pm, "grocery_stocker" wrote:
> >> Here is a copy a persons code I saw on a blog. The only difference
> >> here is that I enable warnings use my().
>
> >> #!/usr/bin/perl -w
>
> >> my @array = qw(ugh geeze blah test smith bob homes point);
>
> >> my $num = "10";
>
> >> for(1..$num) {
> >> my $pid = fork();
> >> if ($pid) {
> >> # parent
> >> push(@childs, $pid);
> >> } elsif ($pid == 0) {
> >> # child
> >> print "@array\n\n";
> >> sleep 5;
> >> exit(0);
> >> } else {
> >> die "couldn't fork: $!\n";
> >> }
> >> print "BEFORE FOR BRACKET\n";
>
> >> }
>
> >> print "AFTER FOR BRACKET\n";
>
> >> foreach (@childs) {
> >> waitpid($_, 0);
>
> >> }
>
> >> And here is what I get when I run it a few times...
> > [snip]
> >> [cdalten@localhost perl]$ ./par.pl
> [...]
> >> BEFORE FOR BRACKET
> >> BEFORE FOR BRACKET
> >> ugh geeze blah test smith bob homes point
>
> >> ugh geeze blah test smith bob homes point
>
> > I presume that the above apparent out-of-order results is what you are
> > concerned about?
> [...]
> >> How would I get them in sync?
> >> Would I have to insert another wait() into the child? Just need some ideas
> >> here.
>
> > Move your waitpid() call so that it executes immediately prior to
> > your
> > print "BEFORE FOR BRACKET\n";
> > statement. This way, the parent will wait for the child to complete
> > (and thus write the array) before it proceeds to generate the BEFORE
> > FOR BRACKET line.
>
> If you do that, what's the point of forking in the first place?
>
Maybe I'm really not understanding what you are saying. The script is
a stripped down version of a wrapper program. Anyhow, I think I got it
running parallel. Here is the output.
#!/usr/bin/perl -w
use File::stat;
use Time::localtime;
my $file="/home/cdalten/perl/out";
my @array = qw(ugh geeze blah test smith bob homes point);
my $num = "50";
for(1..$num) {
my $pid = fork();
if ($pid) {
# parent
push(@childs, $pid);
my $oldfh = select(STDOUT); $| = 1; select ($oldfh);
} elsif ($pid == 0) {
# child
#my $oldfh = select(STDOUT); $| = 1;
print "@array\n";
#$oldfh = select(STDOUT); $| = 1; select($oldfh);
#sleep 5;
exit(0);
} else {
die "couldn't fork: $!\n";
}
#my $olderfh = select(STDOUT); $| = 1;
foreach (@childs) {
waitpid($_, 0);
}
$date_string = ctime(stat($file)->mtime);
print "file $file updated at $date_string\n";
print "BEFORE FOR BRACKET\n";
#$olderfh = select(STDOUT); $| = 1; select($olderfh);
}
#$oldestfh = select(STDOUT); $| = 1; select($oldestfh);
print "AFTER FOR BRACKET\n";
#$date_string = ctime(stat($file)->mtime);
#print "file $file updated at $date_string\n";
#print " $atime, $mtime \n";
#$oldestfh = select(STDOUT); $| = 1; select($oldestfh);
#foreach (@childs) {
# waitpid($_, 0);
#}
Yes, I know that when I redirect a fork to a output file, I need to
probably flush the buffer. However, I was just testing to see if I
would get the same timestamp on the print statements for all the
forks. If the timestamps where the same, then the program in running
in parallel.
[cdalten@localhost perl]$ ./par.pl > out
[cdalten@localhost perl]$ more out
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
-
Re: How to resolve funky sync issues with fork here.
On Apr 5, 6:05 am, "Peter J. Holzer" wrote:
> ["Followup-To:" header set to comp.lang.perl.misc.]
> On 2007-04-04 12:22, Lew Pitcher wrote:
>
>
>
> > On Apr 3, 9:27 pm, "grocery_stocker" wrote:
> >> Here is a copy a persons code I saw on a blog. The only difference
> >> here is that I enable warnings use my().
>
> >> #!/usr/bin/perl -w
>
> >> my @array = qw(ugh geeze blah test smith bob homes point);
>
> >> my $num = "10";
>
> >> for(1..$num) {
> >> my $pid = fork();
> >> if ($pid) {
> >> # parent
> >> push(@childs, $pid);
> >> } elsif ($pid == 0) {
> >> # child
> >> print "@array\n\n";
> >> sleep 5;
> >> exit(0);
> >> } else {
> >> die "couldn't fork: $!\n";
> >> }
> >> print "BEFORE FOR BRACKET\n";
>
> >> }
>
> >> print "AFTER FOR BRACKET\n";
>
> >> foreach (@childs) {
> >> waitpid($_, 0);
>
> >> }
>
> >> And here is what I get when I run it a few times...
> > [snip]
> >> [cdalten@localhost perl]$ ./par.pl
> [...]
> >> BEFORE FOR BRACKET
> >> BEFORE FOR BRACKET
> >> ugh geeze blah test smith bob homes point
>
> >> ugh geeze blah test smith bob homes point
>
> > I presume that the above apparent out-of-order results is what you are
> > concerned about?
> [...]
> >> How would I get them in sync?
> >> Would I have to insert another wait() into the child? Just need some ideas
> >> here.
>
> > Move your waitpid() call so that it executes immediately prior to
> > your
> > print "BEFORE FOR BRACKET\n";
> > statement. This way, the parent will wait for the child to complete
> > (and thus write the array) before it proceeds to generate the BEFORE
> > FOR BRACKET line.
>
> If you do that, what's the point of forking in the first place?
>
> hp
>
> --
> _ | Peter J. Holzer | Blaming Perl for the inability of programmers
> |_|_) | Sysadmin WSR | to write clearly is like blaming English for
> | | | h...@hjp.at | the circumlocutions of bureaucrats.
> __/ |http://www.hjp.at/| -- Charlton Wilbur in clpm
Maybe I'm really not understanding what you are saying. The script is
a stripped down version of a wrapper program. Anyhow, I think I got it
running parallel. Here is the output.
#!/usr/bin/perl -w
use File::stat;
use Time::localtime;
my $file="/home/cdalten/perl/out";
my @array = qw(ugh geeze blah test smith bob homes point);
my $num = "50";
for(1..$num) {
my $pid = fork();
if ($pid) {
# parent
push(@childs, $pid);
my $oldfh = select(STDOUT); $| = 1; select ($oldfh);
} elsif ($pid == 0) {
# child
#my $oldfh = select(STDOUT); $| = 1;
print "@array\n";
#$oldfh = select(STDOUT); $| = 1; select($oldfh);
#sleep 5;
exit(0);
} else {
die "couldn't fork: $!\n";
}
#my $olderfh = select(STDOUT); $| = 1;
foreach (@childs) {
waitpid($_, 0);
}
$date_string = ctime(stat($file)->mtime);
print "file $file updated at $date_string\n";
print "BEFORE FOR BRACKET\n";
#$olderfh = select(STDOUT); $| = 1; select($olderfh);
}
#$oldestfh = select(STDOUT); $| = 1; select($oldestfh);
print "AFTER FOR BRACKET\n";
#$date_string = ctime(stat($file)->mtime);
#print "file $file updated at $date_string\n";
#print " $atime, $mtime \n";
#$oldestfh = select(STDOUT); $| = 1; select($oldestfh);
#foreach (@childs) {
# waitpid($_, 0);
#}
Yes, I know that when I redirect a fork to a output file, I need to
probably flush the buffer. However, I was just testing to see if I
would get the same timestamp on the print statements for all the
forks. If the timestamps is the same, then the program is running
in parallel. Here is part of the output.
[cdalten@localhost perl]$ ./par.pl > out
[cdalten@localhost perl]$ more out
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
ugh geeze blah test smith bob homes point
file /home/cdalten/perl/out updated at Thu Apr 5 06:28:54 2007
BEFORE FOR BRACKET
-
Re: How to resolve funky sync issues with fork here.
["Followup-To:" header set to comp.lang.perl.misc.]
On 2007-04-05 13:34, grocery_stocker wrote:
> On Apr 5, 6:05 am, "Peter J. Holzer" wrote:
>> On 2007-04-04 12:22, Lew Pitcher wrote:
>>
>>
>>
>> > On Apr 3, 9:27 pm, "grocery_stocker" wrote:
>> >> Here is a copy a persons code I saw on a blog. The only difference
>> >> here is that I enable warnings use my().
>>
>> >> #!/usr/bin/perl -w
>>
>> >> my @array = qw(ugh geeze blah test smith bob homes point);
>>
>> >> my $num = "10";
>>
>> >> for(1..$num) {
>> >> my $pid = fork();
>> >> if ($pid) {
>> >> # parent
>> >> push(@childs, $pid);
>> >> } elsif ($pid == 0) {
>> >> # child
>> >> print "@array\n\n";
>> >> sleep 5;
>> >> exit(0);
>> >> } else {
>> >> die "couldn't fork: $!\n";
>> >> }
>> >> print "BEFORE FOR BRACKET\n";
>>
>> >> }
>>
>> >> print "AFTER FOR BRACKET\n";
>>
>> >> foreach (@childs) {
>> >> waitpid($_, 0);
>>
>> >> }
>>
>> > Move your waitpid() call so that it executes immediately prior to
>> > your
>> > print "BEFORE FOR BRACKET\n";
>> > statement. This way, the parent will wait for the child to complete
>> > (and thus write the array) before it proceeds to generate the BEFORE
>> > FOR BRACKET line.
>>
>> If you do that, what's the point of forking in the first place?
>>
>
> Maybe I'm really not understanding what you are saying. The script is
> a stripped down version of a wrapper program. Anyhow, I think I got it
> running parallel. Here is the output.
Your original script was running in parallel. But with the change
suggested by Lew, it isn't running in parallel any more:
> #!/usr/bin/perl -w
>
> use File::stat;
> use Time::localtime;
>
> my $file="/home/cdalten/perl/out";
>
>
> my @array = qw(ugh geeze blah test smith bob homes point);
>
> my $num = "50";
> for(1..$num) {
> my $pid = fork();
here you fork exaclty one child
> if ($pid) {
> # parent
> push(@childs, $pid);
> my $oldfh = select(STDOUT); $| = 1; select ($oldfh);
The parent does nothing except remember the pid of the child
>
> } elsif ($pid == 0) {
> # child
> #my $oldfh = select(STDOUT); $| = 1;
>
> print "@array\n";
> #$oldfh = select(STDOUT); $| = 1; select($oldfh);
>
> #sleep 5;
> exit(0);
The child does its work (put the sleep 5 in again to see that it takes
some time)
> } else {
> die "couldn't fork: $!\n";
> }
>
> #my $olderfh = select(STDOUT); $| = 1;
> foreach (@childs) {
> waitpid($_, 0);
here you wait for the child. After that, the child is finished.
> }
>
> $date_string = ctime(stat($file)->mtime);
> print "file $file updated at $date_string\n";
Here the parent does some more work.
>
> print "BEFORE FOR BRACKET\n";
> #$olderfh = select(STDOUT); $| = 1; select($olderfh);
>
> }
So at any point you have either a single child running (and the parent
waiting) or no child at all. There is never more than one process which
does work, so you can just forget about the fork and do everything in
the parent.
Now I realize that you probably need several processes running in
parallel, that's why I think Lew's suggestion doesn't make sense.
>
> Yes, I know that when I redirect a fork to a output file, I need to
> probably flush the buffer. However, I was just testing to see if I
> would get the same timestamp on the print statements for all the
> forks. If the timestamps where the same, then the program in running
> in parallel.
You never change the file, so why should its timestamp change?
To return to your original question: First decide what you need to
synchronise - i.e., where (and why!) the parent needs to wait for a
child to do something before continuing or a child needs to wait for the
parent or one child needs to wait for another. Once you know that you
can decide what the appropriate synchronization mechanism is (waitpid
probably isn't - it can only wait for a child process to die), for
example semaphores, file locks, messages written to pipes, etc.
hp
--
_ | Peter J. Holzer | Blaming Perl for the inability of programmers
|_|_) | Sysadmin WSR | to write clearly is like blaming English for
| | | hjp@hjp.at | the circumlocutions of bureaucrats.
__/ | http://www.hjp.at/ | -- Charlton Wilbur in clpm