Re: meddling with forces I can't understand
by GrandFather (Saint) on Oct 24, 2007 at 23:31 UTC
|
Could it be ; $ct**2) is not doing what you think it is? The expression does not alter $ct. It may be that you intended something like $ct += 2.
Update:
I'd expect that you should get a heads up about "useless use of exponentiation (**) in void context" if you are using strictures (use strict; use warnings;). If you are not using strictures I strongly advise that you do!
You should really avoid using global variables ($writeCounter appears to be global).
If @forkarray is local there is no need to initialize it. If it's required outside the sub it should either be passed in by reference or returned to the calling code.
Code in a loop of the form:
if (...) {
...
} else {
last;
}
is cleaner as:
last unless ...;
...
because it removes a level of nesting and makes the condition for last clearer.
An early exit before the second for loop would clean the code up in a similar fashion:
return unless fork ();
for (...) {
...
}
Perl is environmentally friendly - it saves trees
| [reply] [d/l] [select] |
Re: meddling with forces I can't understand
by ikegami (Patriarch) on Oct 25, 2007 at 00:18 UTC
|
exec never returns on success, so for(my $ct = 0; $ct <= $#forkArray; $ct+=3) never gets to execute its body more than once.
You never check if fork or exec succeeds.
You never reap your children.
If I'm not mistaken, you run in the parent what you want to run in the child.
The way in which @forkArray is used is not optimally readable.
for (...) {
...
push(@forkArray, $level);
push(@forkArray, $writeCounter);
push(@forkArray, $nextMerge);
}
for (my $ct = 0; $ct <= $#forkArray; $ct+=3) {
my $level = $forkArray[$ct+0];
my $mergeLast = $forkArray[$ct+1];
my $mergeFirst = $forkArray[$ct+2];
...
}
reads better as
for (...) {
...
push @forkArray, [ $level, $writeCounter, $nextMerge ];
}
foreach (@forkArray) {
my ($level, $mergeLast, $mergeFirst) = $@_;
...
}
| [reply] [d/l] [select] |
|
|
forgive me, but this is the first time i've done any of this. how do i manage these things?
You never check if fork or exec succeeds.
You never reap your children.
If I'm not mistaken, you run in the parent what you want to run in the child.
i have a feeling i'm running in the parent when i should be running in child too, but like i said, i'm not too sure what fork and exec do.
| [reply] |
|
|
You never check if fork or exec succeeds
The documentation for fork and exec covers this.
You never reap your children.
I meant to provide a link to waitpid, one method of doing this.
i'm not too sure what fork and exec do.
fork creates a clone of the current process.
exec replaces the program being run in the current process with another program.
Check the docs of these functions, and perlipc.
| [reply] [d/l] [select] |
|
|
forgive me, but this is the first time i've done any of this. how do i manage these things?
You never check if fork or exec succeeds.
You never reap your children.
If I'm not mistaken, you run in the parent what you want to run in the child.
i have a feeling i'm running in the parent when i should be running in child too, but like i said, i'm not too sure what fork and exec do.
| [reply] |
Re: meddling with forces I can't understand
by pileofrogs (Priest) on Oct 24, 2007 at 23:55 UTC
|
You might have fork backwards. If it returns a true value, you're in the parent, not the child. If it returns a 0 you're in the child. If it returns undef, something is hosed.
| [reply] |
Re: meddling with forces I can't understand
by tuxz0r (Pilgrim) on Oct 25, 2007 at 01:39 UTC
|
What sort of merging are you trying to do? How big are the files your primary program writes to disk?, are the individual files already sorted? Do you need to merge them in sorted order? I think, outside of the fork/exec pointers and discussion, some requirements about what the program needs to do might help with the overall answer.
| [reply] |
|
|
I am merging files for an index, I worked around a hack to allow logarithmic merging without any heap structures just by clever tracking of numbers.
I'd have the in-memory index construction worked out, and the merging of 2 sub-indexes also works nicely, this is the last step in getting it to work, i'd like to have merging of the old indexes going on while new indexes are made. I can also try adding this code to the separate merging file, calling itself recursively or iteratively.
| [reply] |
|
|
So, it looks like you're confident in the merging algorithm, so the real question is spawning the second process to merge the old indexes. Again, the pointers above from other monks are necessary reading if you're going to use fork() and exec(), but in general the following idiom is common:
use POSIX ":sys_wait_h";
my %kids = ();
# Signal Handler for SIGCHLD
sub sigchld_handler{
while (($pid = waitpid(-1, &WNOHANG)) > 0) {
delete $kids{$pid};
}
$SIG{CHLD} = \&sigchld_handler;
}
$SIG{CHLD} = \&sigchld_handler;
# You can repeat this for as many secondary
# processes as you need to merge the old indexes
for (1..3) {
if (my $pid = fork) {
# Parent Process keep track of forked children
$kids{$pid} = 1;
}
else {
# Child process
# ... do merging of old indexes here
sleep(3);
exit 0; # MUST EXIT HERE
}
}
while (keys %kids > 0) {
sleep(1); # wait for all children to finish
}
exit 0;
The SIGCHLD handler is there to let you know which of your child processing doing the merging completed successfully (or not), giving you a way to handle them properly. See the previously pointed to documentation about getting the actual exit value, signal and so forth from the completed child process. But, this framework should be enough to get you going if you have the merging algorithm down pat. | [reply] [d/l] |
Re: meddling with forces I can't understand
by Argel (Prior) on Oct 25, 2007 at 17:33 UTC
|
| [reply] |
Re: meddling with forces I can't understand
by pileofrogs (Priest) on Oct 29, 2007 at 15:39 UTC
|
Here's another piece of advice that applies to nearly every question asked here:
Break your program down into the smallest possible chunk that shows the behavior you are interested in.
In this case, I'd recommend making a script that just prints out "I'm the parent" and "I'm the child". Make them loop while saying that with different sleep values in the loops and get to where you can predict what will happen. Try forking inside a loop.
--Pileofrogs
| [reply] |