Skip to content

Instantly share code, notes, and snippets.

@lukeorland
Last active August 29, 2015 14:21
Show Gist options
  • Save lukeorland/ec087222e0a834af8211 to your computer and use it in GitHub Desktop.
Save lukeorland/ec087222e0a834af8211 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
# References:
# - http://stackoverflow.com/a/800105/492631
use warnings;
use strict;
# fork processes
my $num_cores = 4;
my @children = ();
foreach my $core (1..$num_cores) {
my $child = fork();
if (! $child) { # I am child
print STDERR "running child $core\n";
exec("sleep 2 && echo $core > $core");
exit 0;
}
push @children, $child;
next;
}
print "waiting on children\n";
foreach my $child (@children) {
waitpid( $child, 0 );
}
#!/usr/bin/env perl
# References:
# - http://stackoverflow.com/a/800105/492631
use warnings;
use strict;
# fork processes
my $num_cores = 4;
my $num_jobs = 15;
my @children = ();
my $job = 0;
foreach my $core (1..$num_cores) {
if ($job < $num_jobs) {
my $child = fork();
if (! $child) { # I am child
#print STDERR "running child $core\n";
exec("sleep 1 && echo $job > $job");
exit 0;
}
push @children, $child;
$job = $job + 1;
next;
}
}
while (@children) {
my $old_child = shift @children;
waitpid( $old_child, 0 );
print "child finished\n";
if ($job < $num_jobs) {
my $new_child = fork();
if (! $new_child) { # I am child
exec("sleep 1 && echo $job > $job");
exit 0;
}
$job = $job + 1;
push @children, $new_child;
}
}
@lukeorland
Copy link
Author

The output of running this:

$ time perl para.pl
running child 1
running child 2
running child 3
waiting on children
running child 4
perl para.pl  0.02s user 0.03s system 2% cpu 2.031 total

so it took 2 seconds total, and each subprocess took 2 seconds.

$ head [0-9]
==> 1 <==
1

==> 2 <==
2

==> 3 <==
3

==> 4 <==
4

@mjpost
Copy link

mjpost commented May 27, 2015

Great! What about if you have more jobs than cores? In that case we need to start up next jobs as spots become available.

@lukeorland
Copy link
Author

So parajobs.pl uses a FIFO queue to run through all the jobs. It's not as optimal as a pool, since some jobs might finish before a job ahead of them.

I tested this, and 15 1-second jobs with 4 cores took 4.226 total seconds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment