Implemented --timeout with testsuite. Updated man page for release.

This commit is contained in:
Ole Tange 2011-08-22 01:01:57 +02:00
parent 11ff97cd2e
commit 38b1fe9a41
11 changed files with 247 additions and 81 deletions

20
NEWS
View file

@ -1,3 +1,23 @@
20110822
* --timeout implemented so that slow commands can be killed
* CPU detection improved for Mac OSX. Thanks to Wayne E. Seguin.
* Example of a parallel webcrawler in the man page.
* Backup up PostgreSQL with GNU Parallel. Thanks to Stephane Wirtel.
http://wirtel.be/2011/07/15/rsync_parallel/
* Blog post in Japanese.
http://dminor11th.blogspot.com/2011/08/gnu-parallel.html
* Blog post about optimizing JPEGs. Thanks to Thomas Jost.
http://schnouki.net/2011/07/22/optimizing-jpeg-pictures/
* Bug fixes and man page updates.
20110722 20110722
* niceload: --hard will suspend a program if a limit is reached - as * niceload: --hard will suspend a program if a limit is reached - as

View file

@ -1,4 +1,4 @@
AC_INIT([parallel], [20110722], [bug-parallel@gnu.org]) AC_INIT([parallel], [20110822], [bug-parallel@gnu.org])
AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([ AC_CONFIG_FILES([

View file

@ -4,9 +4,10 @@
Update documentation: Update documentation:
Modified => alpha git blame
Unmodified alpha since last version => beta
Unmodified beta since last version => production Unmodified beta since last version => production
Unmodified alpha since last version => beta
Modified => alpha
== Update version == == Update version ==
@ -188,7 +189,7 @@ official distributions.
Ubuntu people: Log into LaunchPad and on Ubuntu people: Log into LaunchPad and on
https://bugs.launchpad.net/ubuntu/+bug/740630 click 'This bug affect https://bugs.launchpad.net/ubuntu/+bug/740630 click 'This bug affect
me too'. me too'. (The link will only appear when you are logged in)
Debian people: This is the (2 years old) bug to push: Debian people: This is the (2 years old) bug to push:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=518696 http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=518696
@ -205,7 +206,7 @@ that depend on moreutils-parallel will be aware of it.
New in this release: New in this release:
(( timeout )) * --timeout implemented so that slow commands can be killed
* CPU detection improved for Mac OSX. Thanks to Wayne E. Seguin. * CPU detection improved for Mac OSX. Thanks to Wayne E. Seguin.

View file

@ -24,7 +24,7 @@
use strict; use strict;
use Getopt::Long; use Getopt::Long;
$Global::progname="niceload"; $Global::progname="niceload";
$Global::version = 20110722; $Global::version = 20110822;
Getopt::Long::Configure("bundling","require_order"); Getopt::Long::Configure("bundling","require_order");
get_options_from_array(\@ARGV) || die_usage(); get_options_from_array(\@ARGV) || die_usage();
if($::opt_version) { if($::opt_version) {

View file

@ -30,25 +30,25 @@ run 1 second, suspend (3.00-1.00) seconds, run 1 second, suspend
=over 9 =over 9
=item B<-f> I<FACTOR> (alpha testing) =item B<-f> I<FACTOR> (beta testing)
=item B<--factor> I<FACTOR> (alpha testing) =item B<--factor> I<FACTOR> (beta testing)
Suspend time factor. Dynamically set B<-s> as amount over limit * Suspend time factor. Dynamically set B<-s> as amount over limit *
factor. Default is 1. factor. Default is 1.
=item B<-H> (alpha testing) =item B<-H> (beta testing)
=item B<--hard> (alpha testing) =item B<--hard> (beta testing)
Hard limit. B<--hard> will suspend the process until the system is Hard limit. B<--hard> will suspend the process until the system is
under the limits. The default is B<--soft>. under the limits. The default is B<--soft>.
=item B<--io> I<iolimit> (alpha testing) =item B<--io> I<iolimit> (beta testing)
=item B<-I> I<iolimit> (alpha testing) =item B<-I> I<iolimit> (beta testing)
Limit for I/O. The amount of disk I/O will be computed as a value 0 - Limit for I/O. The amount of disk I/O will be computed as a value 0 -
10, where 0 is no I/O and 10 is at least one disk is 100% satuated. 10, where 0 is no I/O and 10 is at least one disk is 100% satuated.
@ -56,18 +56,18 @@ Limit for I/O. The amount of disk I/O will be computed as a value 0 -
B<--io> will set both B<--start-io> and B<run-io>. B<--io> will set both B<--start-io> and B<run-io>.
=item B<--load> I<loadlimit> (alpha testing) =item B<--load> I<loadlimit> (beta testing)
=item B<-L> I<loadlimit> (alpha testing) =item B<-L> I<loadlimit> (beta testing)
Limit for load average. Limit for load average.
B<--load> will set both B<--start-load> and B<run-load>. B<--load> will set both B<--start-load> and B<run-load>.
=item B<--mem> I<memlimit> (alpha testing) =item B<--mem> I<memlimit> (beta testing)
=item B<-M> I<memlimit> (alpha testing) =item B<-M> I<memlimit> (beta testing)
Limit for free memory. This is the amount of bytes available as free Limit for free memory. This is the amount of bytes available as free
+ cache. This limit is treated opposite other limits: If the system + cache. This limit is treated opposite other limits: If the system
@ -81,9 +81,9 @@ respectively.
B<--mem> will set both B<--start-mem> and B<run-mem>. B<--mem> will set both B<--start-mem> and B<run-mem>.
=item B<--noswap> (alpha testing) =item B<--noswap> (beta testing)
=item B<-N> (alpha testing) =item B<-N> (beta testing)
No swapping. If the system is swapping both in and out it is a good No swapping. If the system is swapping both in and out it is a good
indication that the system is memory stressed. indication that the system is memory stressed.
@ -93,88 +93,88 @@ B<--noswap> is over limit if the system is swapping both in and out.
B<--noswap> will set both B<--start-noswap> and B<run-noswap>. B<--noswap> will set both B<--start-noswap> and B<run-noswap>.
=item B<-n> I<niceness> (alpha testing) =item B<-n> I<niceness> (beta testing)
=item B<--nice> I<niceness> (alpha testing) =item B<--nice> I<niceness> (beta testing)
Sets niceness. See B<nice>(1). Sets niceness. See B<nice>(1).
=item B<-p> I<PID> (alpha testing) =item B<-p> I<PID> (beta testing)
=item B<--pid> I<PID> (alpha testing) =item B<--pid> I<PID> (beta testing)
Process ID of process to suspend. Process ID of process to suspend.
=item B<--quote> (alpha testing) =item B<--quote> (beta testing)
=item B<-q> (alpha testing) =item B<-q> (beta testing)
Quote the command line. Useful if the command contains chars like *, Quote the command line. Useful if the command contains chars like *,
$, >, and " that should not be interpreted by the shell. $, >, and " that should not be interpreted by the shell.
=item B<--run-io> I<iolimit> (alpha testing) =item B<--run-io> I<iolimit> (beta testing)
=item B<--ri> I<iolimit> (alpha testing) =item B<--ri> I<iolimit> (beta testing)
=item B<--run-load> I<loadlimit> (alpha testing) =item B<--run-load> I<loadlimit> (beta testing)
=item B<--rl> I<loadlimit> (alpha testing) =item B<--rl> I<loadlimit> (beta testing)
=item B<--run-mem> I<memlimit> (alpha testing) =item B<--run-mem> I<memlimit> (beta testing)
=item B<--rm> I<memlimit> (alpha testing) =item B<--rm> I<memlimit> (beta testing)
Run limit. The running program will be slowed down if the system is Run limit. The running program will be slowed down if the system is
above the limit. See: B<--io>, B<--load>, B<--mem>, B<--noswap>. above the limit. See: B<--io>, B<--load>, B<--mem>, B<--noswap>.
=item B<--start-io> I<iolimit> (alpha testing) =item B<--start-io> I<iolimit> (beta testing)
=item B<--si> I<iolimit> (alpha testing) =item B<--si> I<iolimit> (beta testing)
=item B<--start-load> I<loadlimit> (alpha testing) =item B<--start-load> I<loadlimit> (beta testing)
=item B<--sl> I<loadlimit> (alpha testing) =item B<--sl> I<loadlimit> (beta testing)
=item B<--start-mem> I<memlimit> (alpha testing) =item B<--start-mem> I<memlimit> (beta testing)
=item B<--sm> I<memlimit> (alpha testing) =item B<--sm> I<memlimit> (beta testing)
Start limit. The program will not start until the system is below the Start limit. The program will not start until the system is below the
limit. See: B<--io>, B<--load>, B<--mem>, B<--noswap>. limit. See: B<--io>, B<--load>, B<--mem>, B<--noswap>.
=item B<--soft> (alpha testing) =item B<--soft> (beta testing)
=item B<-S> (alpha testing) =item B<-S> (beta testing)
Soft limit. B<niceload> will suspend a process for a while and then Soft limit. B<niceload> will suspend a process for a while and then
let it run for a second thus only slowing down a process while the let it run for a second thus only slowing down a process while the
system is over one of the given limits. This is the default. system is over one of the given limits. This is the default.
=item B<--suspend> I<SEC> (alpha testing) =item B<--suspend> I<SEC> (beta testing)
=item B<-s> I<SEC> (alpha testing) =item B<-s> I<SEC> (beta testing)
Suspend time. Suspend the command this many seconds when the max load Suspend time. Suspend the command this many seconds when the max load
average is reached. average is reached.
=item B<--recheck> I<SEC> (alpha testing) =item B<--recheck> I<SEC> (beta testing)
=item B<-t> I<SEC> (alpha testing) =item B<-t> I<SEC> (beta testing)
Recheck load time. Sleep SEC seconds before checking load Recheck load time. Sleep SEC seconds before checking load
again. Default is 1 second. again. Default is 1 second.
=item B<--verbose> (alpha testing) =item B<--verbose> (beta testing)
=item B<-v> (alpha testing) =item B<-v> (beta testing)
Verbose. Print some extra output on what is happening. Use B<-v> until Verbose. Print some extra output on what is happening. Use B<-v> until
you know what your are doing. you know what your are doing.

View file

@ -389,6 +389,7 @@ sub options_hash {
"number-of-cores" => \$::opt_number_of_cores, "number-of-cores" => \$::opt_number_of_cores,
"use-cpus-instead-of-cores" => \$::opt_use_cpus_instead_of_cores, "use-cpus-instead-of-cores" => \$::opt_use_cpus_instead_of_cores,
"nice=i" => \$::opt_nice, "nice=i" => \$::opt_nice,
"timeout=i" => \$::opt_timeout,
"onall" => \$::opt_onall, "onall" => \$::opt_onall,
"nonall" => \$::opt_nonall, "nonall" => \$::opt_nonall,
"sshlogin|S=s" => \@::opt_sshlogin, "sshlogin|S=s" => \@::opt_sshlogin,
@ -482,7 +483,7 @@ sub get_options_from_array {
sub parse_options { sub parse_options {
# Returns: N/A # Returns: N/A
# Defaults: # Defaults:
$Global::version = 20110819; $Global::version = 20110822;
$Global::progname = 'parallel'; $Global::progname = 'parallel';
$Global::infinity = 2**31; $Global::infinity = 2**31;
$Global::debug = 0; $Global::debug = 0;
@ -538,6 +539,7 @@ sub parse_options {
} }
if(defined $::opt_E) { $Global::end_of_file_string = $::opt_E; } if(defined $::opt_E) { $Global::end_of_file_string = $::opt_E; }
if(defined $::opt_n) { $Global::max_number_of_args = $::opt_n; } if(defined $::opt_n) { $Global::max_number_of_args = $::opt_n; }
if(defined $::opt_timeout) { $Global::timeoutq = TimeoutQueue->new($::opt_timeout); }
if(defined $::opt_tmpdir) { $ENV{'TMPDIR'} = $::opt_tmpdir; } if(defined $::opt_tmpdir) { $ENV{'TMPDIR'} = $::opt_tmpdir; }
if(defined $::opt_help) { die_usage(); } if(defined $::opt_help) { die_usage(); }
if(defined $::opt_colsep) { $Global::trim = 'lr'; } if(defined $::opt_colsep) { $Global::trim = 'lr'; }
@ -1579,6 +1581,20 @@ sub reaper {
return $children_reaped; return $children_reaped;
} }
sub timeout {
# SIGALRM was received. Check if there was a timeout
# @Global::timeout is sorted by timeout
while (@Global::timeouts) {
my $t = $Global::timeouts[0];
if($t->timed_out()) {
$t->kill();
shift @Global::timeouts;
} else {
# Because they are sorted by timeout
last;
}
}
}
sub __USAGE__ {} sub __USAGE__ {}
sub wait_and_exit { sub wait_and_exit {
@ -1735,6 +1751,10 @@ sub usleep {
my $secs = shift; my $secs = shift;
::debug("Sleeping ",$secs," millisecs\n"); ::debug("Sleeping ",$secs," millisecs\n");
select(undef, undef, undef, $secs/1000); select(undef, undef, undef, $secs/1000);
if($::opt_timeout) {
::debug(my_dump($Global::timeoutq));
$Global::timeoutq->process_timeouts();
}
} }
sub multiply_binary_prefix { sub multiply_binary_prefix {
@ -2758,6 +2778,8 @@ sub new {
'sshlogin_wrap' => undef, 'sshlogin_wrap' => undef,
'exitstatus' => undef, 'exitstatus' => undef,
'exitsignal' => undef, 'exitsignal' => undef,
# Timestamp for timeout if any
'timeout' => undef,
}, ref($class) || $class; }, ref($class) || $class;
} }
@ -2893,6 +2915,38 @@ sub set_endtime {
} }
sub set_timeout {
my $self = shift;
my $delta_time = shift;
$self->{'timeout'} = time + $delta_time;
}
sub timeout {
my $self = shift;
return $self->{'timeout'};
}
sub timedout {
my $self = shift;
return time > $self->{'timeout'};
}
sub kill {
# kill the jobs
my $self = shift;
my $pid = $self->pid();
for my $signal ("TERM", "TERM", "KILL") {
# Send two TERMs to give time to clean up
if(kill 0, $pid) {
# The job still running
kill $signal, $pid;
if($signal eq "TERM") { ::usleep(200); }
} else {
# The job is already finished
last;
}
}
}
sub failed { sub failed {
# return number of times failed for this $sshlogin # return number of times failed for this $sshlogin
my $self = shift; my $self = shift;
@ -3289,6 +3343,11 @@ sub start {
} }
$job->set_pid($pid); $job->set_pid($pid);
$job->set_starttime(); $job->set_starttime();
if($::opt_timeout) {
# Timeout must be set before inserting into queue
$job->set_timeout($::opt_timeout);
$Global::timeoutq->insert($job);
}
return $job; return $job;
} }
@ -4213,7 +4272,8 @@ sub new {
my $fhs = shift; my $fhs = shift;
for my $fh (@$fhs) { for my $fh (@$fhs) {
if(-t $fh) { if(-t $fh) {
print STDERR "$Global::progname: Input is tty. ". print STDERR "$Global::progname: Input is read from the terminal. ".
"Only experts do this on purpose. ".
"Press CTRL-D to exit.\n"; "Press CTRL-D to exit.\n";
} }
} }
@ -4495,6 +4555,60 @@ sub trim_of {
} }
package TimeoutQueue;
sub new {
my $class = shift;
my $delta_time = shift;
return bless {
'queue' => [],
'delta_time' => $delta_time,
}, ref($class) || $class;
}
sub process_timeouts {
# Check if there was a timeout
my $self = shift;
# @Global::timeout is sorted by timeout
while (@{$self->{'queue'}}) {
my $job = $self->{'queue'}[0];
if($job->timedout()) {
# Need to shift off queue before kill
# because kill calls usleep -> process_timeouts
shift @{$self->{'queue'}};
$job->kill();
} else {
# Because they are sorted by timeout
last;
}
}
}
sub insert {
my $self = shift;
my $in = shift;
my $lower = 0;
my $upper = $#{$self->{'queue'}};
my $looking = int(($lower + $upper)/2);
my $in_time = $in->timeout();
# Find the position between $lower and $upper
while($lower < $upper) {
if($self->{'queue'}[$looking]->timeout() < $in_time) {
# Upper half
$lower = $looking+1;
} else {
# Lower half
$upper = $looking;
}
$looking = int(($lower + $upper)/2);
}
# splice at position $looking
splice @{$self->{'queue'}}, $looking, 0, $in;
}
package Semaphore; package Semaphore;
# This package provides a counting semaphore # This package provides a counting semaphore
@ -4535,6 +4649,7 @@ sub new {
sub acquire { sub acquire {
my $self = shift; my $self = shift;
my $sleep = 1; # 1 ms my $sleep = 1; # 1 ms
my $start_time = time;
while(1) { while(1) {
$self->atomic_link_if_count_less_than() and last; $self->atomic_link_if_count_less_than() and last;
::debug("Remove dead locks"); ::debug("Remove dead locks");
@ -4558,7 +4673,17 @@ sub acquire {
$sleep = ($sleep < 1000) ? ($sleep * 1.1) : ($sleep); $sleep = ($sleep < 1000) ? ($sleep * 1.1) : ($sleep);
# Random to avoid every sleeping job waking up at the same time # Random to avoid every sleeping job waking up at the same time
::usleep(rand()*$sleep); ::usleep(rand()*$sleep);
# TODO if timeout: last if(defined($::opt_timeout) and
$start_time + $::opt_timeout > time) {
# Acquire the lock anyway
if(not -e $self->{'idfile'}) {
open (A, ">", $self->{'idfile'}) or
::die_bug("write_idfile: $self->{'idfile'}");
close A;
}
link $self->{'idfile'}, $self->{'pidfile'};
last;
}
} }
::debug("acquired $self->{'pid'}\n"); ::debug("acquired $self->{'pid'}\n");
} }

View file

@ -73,7 +73,7 @@ alias or a function will not work (see why
http://www.perlmonks.org/index.pl?node_id=484296). http://www.perlmonks.org/index.pl?node_id=484296).
=item B<{}> (alpha testing) =item B<{}> (beta testing)
Input line. This replacement string will be replaced by a full line Input line. This replacement string will be replaced by a full line
read from the input source. The input source is normally stdin read from the input source. The input source is normally stdin
@ -86,7 +86,7 @@ If the command line contains no replacement strings then B<{}> will be
appended to the command line. appended to the command line.
=item B<{.}> (alpha testing) =item B<{.}> (beta testing)
Input line without extension. This replacement string will be replaced Input line without extension. This replacement string will be replaced
by the input with the extension removed. If the input line contains by the input with the extension removed. If the input line contains
@ -102,7 +102,7 @@ The replacement string B<{.}> can be changed with B<-U>.
To understand replacement strings see B<{}>. To understand replacement strings see B<{}>.
=item B<{/}> (alpha testing) =item B<{/}> (beta testing)
Basename of input line. This replacement string will be replaced by Basename of input line. This replacement string will be replaced by
the input with the directory part removed. the input with the directory part removed.
@ -113,7 +113,7 @@ B<--basenamereplace>.
To understand replacement strings see B<{}>. To understand replacement strings see B<{}>.
=item B<{//}> (alpha testing) =item B<{//}> (beta testing)
Dirname of input line. This replacement string will be replaced by the Dirname of input line. This replacement string will be replaced by the
dir of the input line. See B<dirname>(1). dir of the input line. See B<dirname>(1).
@ -124,7 +124,7 @@ B<--dirnamereplace>.
To understand replacement strings see B<{}>. To understand replacement strings see B<{}>.
=item B<{/.}> (alpha testing) =item B<{/.}> (beta testing)
Basename of input line without extension. This replacement string will Basename of input line without extension. This replacement string will
be replaced by the input with the directory and extension part be replaced by the input with the directory and extension part
@ -136,7 +136,7 @@ B<--basenameextensionreplace>.
To understand replacement strings see B<{}>. To understand replacement strings see B<{}>.
=item B<{#}> (alpha testing) =item B<{#}> (beta testing)
Sequence number of the job to run. This replacement string will be Sequence number of the job to run. This replacement string will be
replaced by the sequence number of the job being run. It contains the replaced by the sequence number of the job being run. It contains the
@ -147,7 +147,7 @@ The replacement string B<{#}> can be changed with B<--seqreplace>.
To understand replacement strings see B<{}>. To understand replacement strings see B<{}>.
=item B<{>I<n>B<}> (alpha testing) =item B<{>I<n>B<}> (beta testing)
Argument from input source I<n> or the I<n>'th argument. This Argument from input source I<n> or the I<n>'th argument. This
positional replacement string will be replaced by the input from input positional replacement string will be replaced by the input from input
@ -157,7 +157,7 @@ argument (when used with B<-N>).
To understand replacement strings see B<{}>. To understand replacement strings see B<{}>.
=item B<{>I<n>.B<}> (alpha testing) =item B<{>I<n>.B<}> (beta testing)
Argument from input source I<n> or the I<n>'th argument without Argument from input source I<n> or the I<n>'th argument without
extension. It is a combination of B<{>I<n>B<}> and B<{.}>. extension. It is a combination of B<{>I<n>B<}> and B<{.}>.
@ -170,7 +170,7 @@ extension removed.
To understand positional replacement strings see B<{>I<n>B<}>. To understand positional replacement strings see B<{>I<n>B<}>.
=item B<{>I<n>/B<}> (alpha testing) =item B<{>I<n>/B<}> (beta testing)
Basename of argument from input source I<n> or the I<n>'th argument. Basename of argument from input source I<n> or the I<n>'th argument.
It is a combination of B<{>I<n>B<}> and B<{/}>. It is a combination of B<{>I<n>B<}> and B<{/}>.
@ -183,7 +183,7 @@ directory (if any) removed.
To understand positional replacement strings see B<{>I<n>B<}>. To understand positional replacement strings see B<{>I<n>B<}>.
=item B<{>I<n>/.B<}> (alpha testing) =item B<{>I<n>/.B<}> (beta testing)
Basename of argument from input source I<n> or the I<n>'th argument Basename of argument from input source I<n> or the I<n>'th argument
without extension. It is a combination of B<{>I<n>B<}>, B<{/}>, and without extension. It is a combination of B<{>I<n>B<}>, B<{/}>, and
@ -197,7 +197,7 @@ directory (if any) and extension removed.
To understand positional replacement strings see B<{>I<n>B<}>. To understand positional replacement strings see B<{>I<n>B<}>.
=item B<:::> I<arguments> (beta testing) =item B<:::> I<arguments>
Use arguments from the command line as input source instead of stdin Use arguments from the command line as input source instead of stdin
(standard input). Unlike other options for GNU B<parallel> B<:::> is (standard input). Unlike other options for GNU B<parallel> B<:::> is
@ -233,7 +233,7 @@ B<:::> and B<::::> can be mixed. So these are equivalent:
seq 4 5 | parallel echo {1} {2} {3} :::: <(seq 6 7) - ::: 1 2 3 seq 4 5 | parallel echo {1} {2} {3} :::: <(seq 6 7) - ::: 1 2 3
=item B<::::> I<argfiles> (beta testing) =item B<::::> I<argfiles>
Another way to write B<-a> I<argfile1> B<-a> I<argfile2> ... Another way to write B<-a> I<argfile1> B<-a> I<argfile2> ...
@ -393,9 +393,9 @@ as \n, or an octal or hexadecimal escape code. Octal and
hexadecimal escape codes are understood as for the printf command. hexadecimal escape codes are understood as for the printf command.
Multibyte characters are not supported. Multibyte characters are not supported.
=item B<--dirnamereplace> I<replace-str> (beta testing) =item B<--dirnamereplace> I<replace-str>
=item B<--dnr> I<replace-str> (beta testing) =item B<--dnr> I<replace-str>
Use the replacement string I<replace-str> instead of B<{//}> for Use the replacement string I<replace-str> instead of B<{//}> for
dirname of input line. dirname of input line.
@ -427,7 +427,7 @@ If I<eof-str> is omitted, there is no end of file string. If neither
B<-E> nor B<-e> is used, no end of file string is used. B<-E> nor B<-e> is used, no end of file string is used.
=item B<--eta> (beta testing) =item B<--eta>
Show the estimated number of seconds before finishing. This forces GNU Show the estimated number of seconds before finishing. This forces GNU
B<parallel> to read all jobs before starting to find the number of B<parallel> to read all jobs before starting to find the number of
@ -638,7 +638,7 @@ B<-l 0> is an alias for B<-l 1>.
Implies B<-X> unless B<-m> is set. Implies B<-X> unless B<-m> is set.
=item B<--load> I<max-load> (beta testing) =item B<--load> I<max-load> (alpha testing)
Do not start new jobs on a given computer unless the load is less than Do not start new jobs on a given computer unless the load is less than
I<max-load>. I<max-load> uses the same syntax as B<--jobs>, so I<100%> I<max-load>. I<max-load> uses the same syntax as B<--jobs>, so I<100%>
@ -689,7 +689,7 @@ See also B<-X> for context replace. If in doubt use B<-X> as that will
most likely do what is needed. most likely do what is needed.
=item B<--minversion> I<version> (beta testing) =item B<--minversion> I<version>
Print the version GNU B<parallel> and exit. If the current version of Print the version GNU B<parallel> and exit. If the current version of
GNU B<parallel> is less than I<version> the exit code is GNU B<parallel> is less than I<version> the exit code is
@ -699,7 +699,7 @@ This is useful for scripts that depend on features only available from
a certain version of GNU B<parallel>. a certain version of GNU B<parallel>.
=item B<--nonall> (beta testing) =item B<--nonall> (alpha testing)
B<--onall> with no arguments. Run the command on all computers given B<--onall> with no arguments. Run the command on all computers given
with B<--sshlogin> but take no arguments. GNU B<parallel> will log with B<--sshlogin> but take no arguments. GNU B<parallel> will log
@ -710,7 +710,7 @@ This is useful for running the same command (e.g. uptime) on a list of
servers. servers.
=item B<--onall> (beta testing) =item B<--onall> (alpha testing)
Run all the jobs on all computers given with B<--sshlogin>. GNU Run all the jobs on all computers given with B<--sshlogin>. GNU
B<parallel> will log into B<--jobs> number of computers in parallel B<parallel> will log into B<--jobs> number of computers in parallel
@ -732,9 +732,9 @@ Instead of printing the output to stdout (standard output) the output
of each job is saved in a file and the filename is then printed. of each job is saved in a file and the filename is then printed.
=item B<--pipe> (beta testing) =item B<--pipe>
=item B<--spreadstdin> (beta testing) =item B<--spreadstdin>
Spread input to jobs on stdin (standard input). Read a block of data Spread input to jobs on stdin (standard input). Read a block of data
from stdin (standard input) and give one block of data as input to one from stdin (standard input) and give one block of data as input to one
@ -902,7 +902,7 @@ Use B<--regexp> to interpret B<--recstart> and B<--recend> as regular
expressions. This is slow, however. expressions. This is slow, however.
=item B<--regexp> (beta testing) =item B<--regexp>
Use B<--regexp> to interpret B<--recstart> and B<--recend> as regular Use B<--regexp> to interpret B<--recstart> and B<--recend> as regular
expressions. This is slow, however. expressions. This is slow, however.
@ -1042,9 +1042,9 @@ Do not use the first line of input (used by GNU B<parallel> itself
when called with B<--shebang>). when called with B<--shebang>).
=item B<-S> I<[ncpu/]sshlogin[,[ncpu/]sshlogin[,...]]> (beta testing) =item B<-S> I<[ncpu/]sshlogin[,[ncpu/]sshlogin[,...]]>
=item B<--sshlogin> I<[ncpu/]sshlogin[,[ncpu/]sshlogin[,...]]> (beta testing) =item B<--sshlogin> I<[ncpu/]sshlogin[,[ncpu/]sshlogin[,...]]>
Distribute jobs to remote computers. The jobs will be run on a list of Distribute jobs to remote computers. The jobs will be run on a list of
remote computers. GNU B<parallel> will determine the number of CPU remote computers. GNU B<parallel> will determine the number of CPU
@ -1080,7 +1080,7 @@ B<--sshlogin> is often used with B<--transfer>, B<--return>,
B<--cleanup>, and B<--trc>. B<--cleanup>, and B<--trc>.
=item B<--sshloginfile> I<filename> (beta testing) =item B<--sshloginfile> I<filename>
File with sshlogins. The file consists of sshlogins on separate File with sshlogins. The file consists of sshlogins on separate
lines. Empty lines and lines starting with '#' are ignored. Example: lines. Empty lines and lines starting with '#' are ignored. Example:
@ -1109,7 +1109,8 @@ The sshloginfile '..' is special, it read sshlogins from
The sshloginfile '-' is special, too, it read sshlogins from stdin The sshloginfile '-' is special, too, it read sshlogins from stdin
(standard input). (standard input).
=item B<--noswap> (beta testing)
=item B<--noswap>
Do not start new jobs on a given computer if there is both swap-in and Do not start new jobs on a given computer if there is both swap-in and
swap-out activity. swap-out activity.
@ -1147,6 +1148,13 @@ different dir for the files. Setting B<--tmpdir> is equivalent to
setting $TMPDIR. setting $TMPDIR.
=item B<--timeout> I<sec> (alpha testing)
Time out for command. If the command runs for longer than I<sec>
seconds it will get killed with SIGTERM, followed by SIGTERM 200 ms
later, followed by SIGKILL 200 ms later.
=item B<--tollef> =item B<--tollef>
Make GNU B<parallel> behave like Tollef's parallel command. To Make GNU B<parallel> behave like Tollef's parallel command. To
@ -1313,7 +1321,7 @@ See also B<-m>.
Exit if the size (see the B<-s> option) is exceeded. Exit if the size (see the B<-s> option) is exceeded.
=item B<--xapply> (beta testing) =item B<--xapply>
Read multiple files like B<xapply>. If multiple B<-a> are given, one Read multiple files like B<xapply>. If multiple B<-a> are given, one
line will be read from each of the files. The arguments can be line will be read from each of the files. The arguments can be

View file

@ -536,7 +536,7 @@ $Global::Initfile && unlink $Global::Initfile;
exit ($err); exit ($err);
sub parse_options { sub parse_options {
$Global::version = 20110722; $Global::version = 20110822;
$Global::progname = 'sql'; $Global::progname = 'sql';
# This must be done first as this may exec myself # This must be done first as this may exec myself

View file

@ -1,22 +1,21 @@
#!/bin/bash #!/bin/bash
cat <<'EOF' | sed -e s/\$SERVER1/$SERVER1/\;s/\$SERVER2/$SERVER2/ | nice parallel -j0 -k -L1 #cat <<'EOF' | sed -e s/\$SERVER1/$SERVER1/\;s/\$SERVER2/$SERVER2/ | nice timeout -k 1 40 parallel -j0 -k -L1
echo '### Test of --retries - it should run 13 jobs in total'; echo '### Test of --retries - it should run 13 jobs in total';
seq 0 12 | stdout parallel --progress -kj100% --retries 1 -S 12/localhost,1/:,parallel@server2 -vq seq 0 12 | stdout parallel --progress -kj100% --retries 1 -S 12/localhost,1/:,parallel@server2 -vq \
perl -e 'sleep 1;print "job{}\n";exit({})' | perl -e 'sleep 1;print "job{}\n";exit({})' |
perl -ne 'BEGIN{$/="\r";} @a=(split /\//,$_); END{print $a[1]+$a[4]+$a[7],"\n"}' perl -ne 'BEGIN{$/="\r";} @a=(split /\//,$_); END{print $a[1]+$a[4]+$a[7],"\n"}'
echo '### Test of --retries - it should run 25 jobs in total'; echo '### Test of --retries - it should run 25 jobs in total';
seq 0 12 | stdout parallel --progress -kj100% --retries 2 -S 12/localhost,1/:,parallel@server2 -vq seq 0 12 | stdout parallel --progress -kj100% --retries 2 -S 12/localhost,1/:,parallel@server2 -vq \
perl -e 'sleep 1;print "job{}\n";exit({})' | perl -e 'sleep 1;print "job{}\n";exit({})' |
perl -ne 'BEGIN{$/="\r";} @a=(split /\//,$_); END{print $a[1]+$a[4]+$a[7],"\n"}' perl -ne 'BEGIN{$/="\r";} @a=(split /\//,$_); END{print $a[1]+$a[4]+$a[7],"\n"}'
echo '### Test of --retries - it should run 49 jobs in total'; echo '### Test of --retries - it should run 49 jobs in total';
seq 0 12 | stdout parallel --progress -kj100% --retries 4 -S 12/localhost,1/:,parallel@server2 -vq seq 0 12 | stdout parallel --progress -kj100% --retries 4 -S 12/localhost,1/:,parallel@server2 -vq \
perl -e 'sleep 1;print "job{}\n";exit({})' | perl -e 'sleep 1;print "job{}\n";exit({})' |
perl -ne 'BEGIN{$/="\r";} @a=(split /\//,$_); END{print $a[1]+$a[4]+$a[7],"\n"}' perl -ne 'BEGIN{$/="\r";} @a=(split /\//,$_); END{print $a[1]+$a[4]+$a[7],"\n"}'
EOF #EOF
echo '### Bug with --retries' echo '### Bug with --retries'
seq 1 8 | parallel --retries 2 --sshlogin 8/localhost,8/: -j+0 "hostname; false" | wc -l seq 1 8 | parallel --retries 2 --sshlogin 8/localhost,8/: -j+0 "hostname; false" | wc -l
seq 1 8 | parallel --retries 2 --sshlogin 8/localhost,8/: -j+1 "hostname; false" | wc -l seq 1 8 | parallel --retries 2 --sshlogin 8/localhost,8/: -j+1 "hostname; false" | wc -l

View file

@ -0,0 +1,7 @@
#!/bin/bash
# -L1 will join lines ending in ' '
cat <<'EOF' | sed -e s/\$SERVER1/$SERVER1/\;s/\$SERVER2/$SERVER2/ | parallel -j10 -k -L1
echo '### Test --timeout';
parallel -j0 -k --timeout 1 echo {}\; sleep {}\; echo {} ::: 1.1 2.2 3.3 4.4
EOF

View file

@ -0,0 +1,6 @@
### Test --timeout
1.1
1.1
2.2
3.3
4.4