mirror of
https://git.savannah.gnu.org/git/parallel.git
synced 2024-11-25 23:47:53 +00:00
Unittest for sem
This commit is contained in:
parent
422578c103
commit
ac16e65b8a
|
@ -2,10 +2,10 @@
|
||||||
# sem gzip foo ";" echo done
|
# sem gzip foo ";" echo done
|
||||||
|
|
||||||
# Allow 7 to run. After then 7th is started, block untill one is dead
|
# Allow 7 to run. After then 7th is started, block untill one is dead
|
||||||
parallel --mutex uniqidentifier -j7 command
|
parallel --semaphore --id uniqidentifier -j7 command
|
||||||
parallel --automutex -j7 command
|
parallel --semaphore -j7 command
|
||||||
mdm.screen find dir -execdir mdm-run cmd {} \;
|
mdm.screen find dir -execdir mdm-run cmd {} \;
|
||||||
find dir -execdir parallel --automutex cmd {} \;
|
find dir -execdir parallel --semaphore cmd {} \;
|
||||||
|
|
||||||
fex syntax for splitting fields
|
fex syntax for splitting fields
|
||||||
http://www.semicomplete.com/projects/fex/
|
http://www.semicomplete.com/projects/fex/
|
||||||
|
|
24
src/parallel
24
src/parallel
|
@ -12,6 +12,8 @@ B<parallel> [options] [I<command> [arguments]] B<:::> arguments
|
||||||
|
|
||||||
B<parallel> [options] [I<command> [arguments]] B<::::> argfile(s)
|
B<parallel> [options] [I<command> [arguments]] B<::::> argfile(s)
|
||||||
|
|
||||||
|
B<parallel> --semaphore [options] I<command>
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
GNU B<parallel> is a shell tool for executing jobs in parallel locally
|
GNU B<parallel> is a shell tool for executing jobs in parallel locally
|
||||||
|
@ -342,7 +344,10 @@ use B<-I> instead.
|
||||||
|
|
||||||
=item B<-P> I<N>
|
=item B<-P> I<N>
|
||||||
|
|
||||||
Run up to N jobs in parallel. 0 means as many as possible. Default is 9.
|
Run up to N jobs in parallel. 0 means as many as possible. Default is
|
||||||
|
9.
|
||||||
|
|
||||||
|
If B<--semaphore> is set default is 1 thus making a mutex.
|
||||||
|
|
||||||
|
|
||||||
=item B<--jobs> I<+N>
|
=item B<--jobs> I<+N>
|
||||||
|
@ -580,6 +585,18 @@ operating system and the B<-s> option. Pipe the input from /dev/null
|
||||||
to do anything.
|
to do anything.
|
||||||
|
|
||||||
|
|
||||||
|
=item B<--semaphore> (not implemented)
|
||||||
|
|
||||||
|
Work as a counting semaphore. B<--semaphore> will cause GNU
|
||||||
|
B<parallel> to start I<command> in the background. When the number of
|
||||||
|
simultaneous jobs is reached, GNU B<parallel> will wait for one of
|
||||||
|
these to complete before starting another command.
|
||||||
|
|
||||||
|
Used with B<--fg> and B<--semaphorename>.
|
||||||
|
|
||||||
|
The command B<sem> is an alias for B<parallel --semaphore>.
|
||||||
|
|
||||||
|
|
||||||
=item B<-S> I<[ncpu/]sshlogin[,[ncpu/]sshlogin[,...]]>
|
=item B<-S> I<[ncpu/]sshlogin[,[ncpu/]sshlogin[,...]]>
|
||||||
|
|
||||||
=item B<--sshlogin> I<[ncpu/]sshlogin[,[ncpu/]sshlogin[,...]]>
|
=item B<--sshlogin> I<[ncpu/]sshlogin[,[ncpu/]sshlogin[,...]]>
|
||||||
|
@ -784,6 +801,11 @@ To compress all html files using B<gzip> run:
|
||||||
|
|
||||||
B<find . -name '*.html' | parallel gzip>
|
B<find . -name '*.html' | parallel gzip>
|
||||||
|
|
||||||
|
If the file names may contain a newline use B<-0>. Substitute FOO BAR with
|
||||||
|
FUBAR in all files in this dir and subdirs:
|
||||||
|
|
||||||
|
B<find . -type f -print0 | parallel -q0 perl -i -pe 's/FOO BAR/FUBAR/g'>
|
||||||
|
|
||||||
|
|
||||||
=head1 EXAMPLE: Reading arguments from command line
|
=head1 EXAMPLE: Reading arguments from command line
|
||||||
|
|
||||||
|
|
39
src/sem
39
src/sem
|
@ -36,7 +36,8 @@ Command to execute. The command may be followed by arguments for the command.
|
||||||
|
|
||||||
=item B<-j> I<N>
|
=item B<-j> I<N>
|
||||||
|
|
||||||
Run up to N commands in parallel. Default is 9.
|
Run up to N commands in parallel. Default is 1 thus acting like a
|
||||||
|
mutex.
|
||||||
|
|
||||||
|
|
||||||
=item B<--id> I<id>
|
=item B<--id> I<id>
|
||||||
|
@ -91,21 +92,13 @@ Report bugs to <bug-parallel@gnu.org>.
|
||||||
|
|
||||||
=head1 AUTHOR
|
=head1 AUTHOR
|
||||||
|
|
||||||
Copyright (C) 2007-10-18 Ole Tange, http://ole.tange.dk
|
|
||||||
|
|
||||||
Copyright (C) 2008,2009,2010 Ole Tange, http://ole.tange.dk
|
|
||||||
|
|
||||||
Copyright (C) 2010 Ole Tange, http://ole.tange.dk and Free Software
|
Copyright (C) 2010 Ole Tange, http://ole.tange.dk and Free Software
|
||||||
Foundation, Inc.
|
Foundation, Inc.
|
||||||
|
|
||||||
Parts of the manual concerning B<xargs> compatibility is inspired by
|
|
||||||
the manual of B<xargs> from GNU findutils 4.4.2.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
=head1 LICENSE
|
=head1 LICENSE
|
||||||
|
|
||||||
Copyright (C) 2007,2008,2009,2010 Free Software Foundation, Inc.
|
Copyright (C) 2010 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -223,10 +216,9 @@ B<parallel>(1)
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
use strict;
|
||||||
use Symbol qw(gensym);
|
use Symbol qw(gensym);
|
||||||
#use strict;
|
|
||||||
use Getopt::Long;
|
use Getopt::Long;
|
||||||
use Fcntl 'LOCK_EX', 'LOCK_NB';
|
|
||||||
|
|
||||||
Getopt::Long::Configure ("bundling","require_order");
|
Getopt::Long::Configure ("bundling","require_order");
|
||||||
GetOptions("debug|D" => \$::opt_D,
|
GetOptions("debug|D" => \$::opt_D,
|
||||||
|
@ -241,7 +233,7 @@ $Global::debug = $::opt_D;
|
||||||
$Global::version = 20100814;
|
$Global::version = 20100814;
|
||||||
$Global::progname = 'sem';
|
$Global::progname = 'sem';
|
||||||
|
|
||||||
my $count = 9; # Default 9
|
my $count = 1; # Default 1 = mutex
|
||||||
if($::opt_count) {
|
if($::opt_count) {
|
||||||
$count = $::opt_count + 1;
|
$count = $::opt_count + 1;
|
||||||
}
|
}
|
||||||
|
@ -251,6 +243,9 @@ if($::opt_wait) {
|
||||||
my $id = $::opt_id;
|
my $id = $::opt_id;
|
||||||
my $fg = $::opt_fg || $::opt_wait;
|
my $fg = $::opt_fg || $::opt_wait;
|
||||||
$::opt_timeout = $::opt_timeout;
|
$::opt_timeout = $::opt_timeout;
|
||||||
|
if(defined $::opt_version) {
|
||||||
|
version();
|
||||||
|
}
|
||||||
|
|
||||||
if(not defined $id) {
|
if(not defined $id) {
|
||||||
# $id = getppid();
|
# $id = getppid();
|
||||||
|
@ -312,16 +307,28 @@ sub debug {
|
||||||
# Returns: N/A
|
# Returns: N/A
|
||||||
$Global::debug or return;
|
$Global::debug or return;
|
||||||
@_ = grep { defined $_ ? $_ : "" } @_;
|
@_ = grep { defined $_ ? $_ : "" } @_;
|
||||||
print @_;
|
print map {$_,"\n" } @_;
|
||||||
}
|
}
|
||||||
|
|
||||||
package Semaphore;
|
package Semaphore;
|
||||||
|
|
||||||
|
# This package provides a counting semaphore
|
||||||
|
#
|
||||||
|
# If a process dies without releasing the semaphore the next process
|
||||||
|
# that needs that entry will clean up dead semaphores
|
||||||
|
#
|
||||||
|
# The semaphores are stored in ~/.parallel/semaphores/id-<name> Each
|
||||||
|
# file in ~/.parallel/semaphores/id-<name>/ is the process ID of the
|
||||||
|
# process holding the entry. If the process dies, the entry can be
|
||||||
|
# taken by another process.
|
||||||
|
|
||||||
|
use Fcntl qw(:DEFAULT :flock);
|
||||||
|
|
||||||
sub new {
|
sub new {
|
||||||
my $class = shift;
|
my $class = shift;
|
||||||
my $id = shift;
|
my $id = shift;
|
||||||
my $count = shift;
|
my $count = shift;
|
||||||
my $parallel_locks = $ENV{'HOME'}."/.parallel/locks";
|
my $parallel_locks = $ENV{'HOME'}."/.parallel/semaphores";
|
||||||
-d $parallel_locks or mkdir $parallel_locks;
|
-d $parallel_locks or mkdir $parallel_locks;
|
||||||
my $lockdir = "$parallel_locks/$id";
|
my $lockdir = "$parallel_locks/$id";
|
||||||
my $lockfile = $lockdir.".lock";
|
my $lockfile = $lockdir.".lock";
|
||||||
|
@ -408,7 +415,7 @@ sub lock {
|
||||||
open $self->{'lockfh'}, ">", $self->{'lockfile'}
|
open $self->{'lockfh'}, ">", $self->{'lockfile'}
|
||||||
or die "Can't open semaphore file $self->{'lockfile'}: $!";
|
or die "Can't open semaphore file $self->{'lockfile'}: $!";
|
||||||
chmod 0666, $self->{'lockfile'}; # assuming you want it a+rw
|
chmod 0666, $self->{'lockfile'}; # assuming you want it a+rw
|
||||||
while(not flock $self->{'lockfh'}, LOCK_EX|LOCK_NB) {
|
while(not flock $self->{'lockfh'}, LOCK_EX()|LOCK_NB()) {
|
||||||
::debug("Cannot lock $self->{'lockfile'}");
|
::debug("Cannot lock $self->{'lockfile'}");
|
||||||
# TODO if timeout: last
|
# TODO if timeout: last
|
||||||
sleep 1;
|
sleep 1;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
export LANG=C
|
export LANG=C
|
||||||
SHFILE=/tmp/unittest-parallel.sh
|
SHFILE=/tmp/unittest-parallel.sh
|
||||||
|
|
||||||
ls -t tests-to-run/test*.sh \
|
ls -t tests-to-run/*.sh \
|
||||||
| perl -pe 's:(.*/(.*)).sh:bash $1.sh > actual-results/$2; diff -Naur wanted-results/$2 actual-results/$2:' \
|
| perl -pe 's:(.*/(.*)).sh:bash $1.sh > actual-results/$2; diff -Naur wanted-results/$2 actual-results/$2:' \
|
||||||
>$SHFILE
|
>$SHFILE
|
||||||
|
|
||||||
|
|
9
unittest/tests-to-run/sem01.sh
Executable file
9
unittest/tests-to-run/sem01.sh
Executable file
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo '### Test mutex. This should take 3 seconds'
|
||||||
|
sem 'sleep 1; echo foo'
|
||||||
|
sem 'sleep 1; echo foo'
|
||||||
|
sem 'sleep 1; echo foo'
|
||||||
|
sem --wait
|
||||||
|
|
||||||
|
|
4
unittest/wanted-results/sem01
Normal file
4
unittest/wanted-results/sem01
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
### Test mutex. This should take 3 seconds
|
||||||
|
foo
|
||||||
|
foo
|
||||||
|
foo
|
Loading…
Reference in a new issue