mirror of
https://git.savannah.gnu.org/git/parallel.git
synced 2024-11-24 23:17:55 +00:00
parallel: Fixed bug in optimized finding (grand)*parent shell.
This commit is contained in:
parent
7aa0394278
commit
a24bef3d03
|
@ -222,9 +222,9 @@ Quote of the month:
|
||||||
|
|
||||||
New in this release:
|
New in this release:
|
||||||
|
|
||||||
* {= uq; =} will cause the replacement string to be unquoted. Example: parallel echo '{=uq;=}.jpg' ::: '*'
|
* {= uq; =} causes the replacement string to be unquoted. Example: parallel echo '{=uq;=}.jpg' ::: '*'
|
||||||
|
|
||||||
* Speedup of startup by 40%: Find the parent shell differerently on GNU/Linux, cache information about the CPU and which setpgrp method to make GNU Parallel start 40% faster.
|
* Speedup of startup by 40%: Find the parent shell differerently on GNU/Linux, cache information about the CPU and which setpgrp method to use to make GNU Parallel start 40% faster.
|
||||||
|
|
||||||
https://techieroop.com/how-to-run-multiple-bash-scripts-in-parallel/
|
https://techieroop.com/how-to-run-multiple-bash-scripts-in-parallel/
|
||||||
|
|
||||||
|
|
34
src/parallel
34
src/parallel
|
@ -19,8 +19,7 @@
|
||||||
|
|
||||||
# open3 used in Job::start
|
# open3 used in Job::start
|
||||||
use IPC::Open3;
|
use IPC::Open3;
|
||||||
# &WNOHANG used in reaper
|
use POSIX;
|
||||||
use POSIX qw(:sys_wait_h setsid ceil :errno_h);
|
|
||||||
# gensym used in Job::start
|
# gensym used in Job::start
|
||||||
use Symbol qw(gensym);
|
use Symbol qw(gensym);
|
||||||
# tempfile used in Job::start
|
# tempfile used in Job::start
|
||||||
|
@ -5080,7 +5079,7 @@ sub tmpname($) {
|
||||||
|
|
||||||
sub tmpfifo() {
|
sub tmpfifo() {
|
||||||
# Find an unused name and mkfifo on it
|
# Find an unused name and mkfifo on it
|
||||||
use POSIX qw(mkfifo);
|
# use POSIX qw(mkfifo);
|
||||||
my $tmpfifo = tmpname("fif");
|
my $tmpfifo = tmpname("fif");
|
||||||
mkfifo($tmpfifo,0600);
|
mkfifo($tmpfifo,0600);
|
||||||
return $tmpfifo;
|
return $tmpfifo;
|
||||||
|
@ -5426,7 +5425,7 @@ sub which(@) {
|
||||||
"-sh (sh)" => ["sh"],
|
"-sh (sh)" => ["sh"],
|
||||||
# csh and tcsh disguise themselves as -sh/-csh
|
# csh and tcsh disguise themselves as -sh/-csh
|
||||||
# E.g.: ssh -tt csh@lo 'ps aux;true' |egrep ^csh
|
# E.g.: ssh -tt csh@lo 'ps aux;true' |egrep ^csh
|
||||||
# but sh also disguise itself as -sh
|
# but sh also disguises itself as -sh
|
||||||
# (TODO When does that happen?)
|
# (TODO When does that happen?)
|
||||||
"-sh" => ["sh"],
|
"-sh" => ["sh"],
|
||||||
"-csh" => ["tcsh", "csh"],
|
"-csh" => ["tcsh", "csh"],
|
||||||
|
@ -5446,16 +5445,35 @@ sub which(@) {
|
||||||
# Optimized for GNU/Linux
|
# Optimized for GNU/Linux
|
||||||
my $testpid = $pid;
|
my $testpid = $pid;
|
||||||
my $shellpath;
|
my $shellpath;
|
||||||
|
my $shellline;
|
||||||
while($testpid) {
|
while($testpid) {
|
||||||
|
if(open(my $fd, "<", "/proc/$testpid/cmdline")) {
|
||||||
|
local $/="\0";
|
||||||
|
chomp($shellline = <$fd>);
|
||||||
|
if($shellline =~ /$regexp/o) {
|
||||||
|
my $shellname = $4 || $8;
|
||||||
|
my $dash = $3 || $7;
|
||||||
|
if($shellname eq "sh" and $dash) {
|
||||||
|
# -sh => csh or sh
|
||||||
if($shellpath = readlink "/proc/$testpid/exe") {
|
if($shellpath = readlink "/proc/$testpid/exe") {
|
||||||
|
::debug("init","procpath $shellpath\n");
|
||||||
if($shellpath =~ m:/$shell$:o) {
|
if($shellpath =~ m:/$shell$:o) {
|
||||||
::debug("init", "proc which ".$shellpath." => ");
|
::debug("init", "proc which ".$shellpath." => ");
|
||||||
return $shellpath;
|
return $shellpath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
::debug("init", "which ".$shellname." => ");
|
||||||
|
$shellpath = (which($shellname,@{$fakename{$shellname}}))[0];
|
||||||
|
::debug("init", "shell path $shellpath\n");
|
||||||
|
return $shellpath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# Get parent pid
|
||||||
if(open(my $fd, "<", "/proc/$testpid/stat")) {
|
if(open(my $fd, "<", "/proc/$testpid/stat")) {
|
||||||
my $line = <$fd>;
|
my $line = <$fd>;
|
||||||
close $fd;
|
close $fd;
|
||||||
|
# Parent pid is field 4
|
||||||
$testpid = (split /\s+/, $line)[3];
|
$testpid = (split /\s+/, $line)[3];
|
||||||
} else {
|
} else {
|
||||||
# Something is wrong: fall back to old method
|
# Something is wrong: fall back to old method
|
||||||
|
@ -6995,8 +7013,9 @@ sub socket_core_thread() {
|
||||||
::hostname() . "/cpuspec";
|
::hostname() . "/cpuspec";
|
||||||
if(-e $cached_cpuspec and -M $cached_cpuspec < 1) {
|
if(-e $cached_cpuspec and -M $cached_cpuspec < 1) {
|
||||||
# Reading cached copy instead of /proc/cpuinfo is 17 ms faster
|
# Reading cached copy instead of /proc/cpuinfo is 17 ms faster
|
||||||
|
local $/ = "\n";
|
||||||
if(open(my $in_fh, "<", $cached_cpuspec)) {
|
if(open(my $in_fh, "<", $cached_cpuspec)) {
|
||||||
::debug("init","Read $cached_cpuspec");
|
::debug("init","Read $cached_cpuspec\n");
|
||||||
$cpu->{'sockets'} = int(<$in_fh>);
|
$cpu->{'sockets'} = int(<$in_fh>);
|
||||||
$cpu->{'cores'} = int(<$in_fh>);
|
$cpu->{'cores'} = int(<$in_fh>);
|
||||||
$cpu->{'threads'} = int(<$in_fh>);
|
$cpu->{'threads'} = int(<$in_fh>);
|
||||||
|
@ -8144,12 +8163,12 @@ sub remove_rec_sep($) {
|
||||||
sub non_blocking_write($) {
|
sub non_blocking_write($) {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $something_written = 0;
|
my $something_written = 0;
|
||||||
use POSIX qw(:errno_h);
|
# use POSIX qw(:errno_h);
|
||||||
|
|
||||||
my $in = $self->fh(0,"w");
|
my $in = $self->fh(0,"w");
|
||||||
my $rv = syswrite($in,
|
my $rv = syswrite($in,
|
||||||
substr($self->{'block'},$self->{'block_pos'}));
|
substr($self->{'block'},$self->{'block_pos'}));
|
||||||
if (!defined($rv) && $! == EAGAIN) {
|
if (!defined($rv) && $! == EAGAIN()) {
|
||||||
# would block - but would have written
|
# would block - but would have written
|
||||||
$something_written = 0;
|
$something_written = 0;
|
||||||
# avoid triggering auto expanding block
|
# avoid triggering auto expanding block
|
||||||
|
@ -9224,6 +9243,7 @@ sub start($) {
|
||||||
my $setgprp_cache = $Global::cache_dir . "/tmp/sshlogin/" .
|
my $setgprp_cache = $Global::cache_dir . "/tmp/sshlogin/" .
|
||||||
::hostname() . "/setpgrp_func";
|
::hostname() . "/setpgrp_func";
|
||||||
if(-e $setgprp_cache) {
|
if(-e $setgprp_cache) {
|
||||||
|
local $/ = undef;
|
||||||
open(my $fh, "<", $setgprp_cache) || die;
|
open(my $fh, "<", $setgprp_cache) || die;
|
||||||
eval <$fh> || die;
|
eval <$fh> || die;
|
||||||
close $fh;
|
close $fh;
|
||||||
|
|
|
@ -742,6 +742,11 @@ par_unquote_replacement_string() {
|
||||||
parallel echo '{}{=uq()=}' ::: '`echo foo`'
|
parallel echo '{}{=uq()=}' ::: '`echo foo`'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
par_delimiter_space() {
|
||||||
|
echo '### Does space as delimiter work?'
|
||||||
|
parallel -d " " echo ::: "1 done"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export -f $(compgen -A function | grep par_)
|
export -f $(compgen -A function | grep par_)
|
||||||
compgen -A function | grep par_ | LC_ALL=C sort |
|
compgen -A function | grep par_ | LC_ALL=C sort |
|
||||||
|
|
|
@ -331,18 +331,26 @@ par_do_not_export_PARALLEL_ENV() {
|
||||||
par_nice() {
|
par_nice() {
|
||||||
echo 'Check that --nice works'
|
echo 'Check that --nice works'
|
||||||
# parallel-20160422 OK
|
# parallel-20160422 OK
|
||||||
|
check_for_2_bzip2s() {
|
||||||
|
perl -e '
|
||||||
|
for(1..5) {
|
||||||
|
# Try 5 times if the machine is slow starting bzip2
|
||||||
|
sleep(1);
|
||||||
|
@out = qx{ps -eo "%c %n" | grep 18 | grep bzip2};
|
||||||
|
if($#out == 1) {
|
||||||
|
# Should find 2 lines
|
||||||
|
print @out;
|
||||||
|
exit 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print "failed\n@out";
|
||||||
|
'
|
||||||
|
}
|
||||||
# wait for load < 8
|
# wait for load < 8
|
||||||
parallel --load 8 echo ::: load_10
|
parallel --load 8 echo ::: load_10
|
||||||
parallel -j0 --timeout 10 --nice 18 bzip2 '<' ::: /dev/zero /dev/zero &
|
parallel -j0 --timeout 10 --nice 18 bzip2 '<' ::: /dev/zero /dev/zero &
|
||||||
pid=$!
|
pid=$!
|
||||||
# Should find 2 lines
|
check_for_2_bzip2s
|
||||||
# Try 5 times if the machine is slow starting bzip2
|
|
||||||
(sleep 1; ps -eo "%c %n" | grep 18 | grep bzip2) ||
|
|
||||||
(sleep 1; ps -eo "%c %n" | grep 18 | grep bzip2) ||
|
|
||||||
(sleep 1; ps -eo "%c %n" | grep 18 | grep bzip2) ||
|
|
||||||
(sleep 1; ps -eo "%c %n" | grep 18 | grep bzip2) ||
|
|
||||||
(sleep 1; ps -eo "%c %n" | grep 18 | grep bzip2) ||
|
|
||||||
(sleep 1; ps -eo "%c %n" | grep 18 | grep bzip2)
|
|
||||||
parallel --retries 10 '! kill -TERM' ::: $pid 2>/dev/null
|
parallel --retries 10 '! kill -TERM' ::: $pid 2>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,9 @@ par_delimiter line 3
|
||||||
par_delimiter delimiter TAB line 1
|
par_delimiter delimiter TAB line 1
|
||||||
par_delimiter line 2
|
par_delimiter line 2
|
||||||
par_delimiter line 3
|
par_delimiter line 3
|
||||||
|
par_delimiter_space ### Does space as delimiter work?
|
||||||
|
par_delimiter_space 1
|
||||||
|
par_delimiter_space done
|
||||||
par_disk_full ### Disk full
|
par_disk_full ### Disk full
|
||||||
par_disk_full cat: write error: No space left on device
|
par_disk_full cat: write error: No space left on device
|
||||||
par_disk_full parallel: Error: Output is incomplete.
|
par_disk_full parallel: Error: Output is incomplete.
|
||||||
|
|
Loading…
Reference in a new issue