mirror of
https://git.savannah.gnu.org/git/parallel.git
synced 2024-11-22 05:57:54 +00:00
Implemented --timeout with testsuite. Updated man page for release.
This commit is contained in:
parent
11ff97cd2e
commit
38b1fe9a41
20
NEWS
20
NEWS
|
@ -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
|
||||||
|
|
|
@ -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([
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
131
src/parallel
131
src/parallel
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
2
src/sql
2
src/sql
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
7
testsuite/tests-to-run/test65.sh
Normal file
7
testsuite/tests-to-run/test65.sh
Normal 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
|
6
testsuite/wanted-results/test65
Normal file
6
testsuite/wanted-results/test65
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
### Test --timeout
|
||||||
|
1.1
|
||||||
|
1.1
|
||||||
|
2.2
|
||||||
|
3.3
|
||||||
|
4.4
|
Loading…
Reference in a new issue