summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKerin Millar <kfm@plushkava.net>2024-06-02 04:42:00 +0100
committerKerin Millar <kfm@plushkava.net>2024-06-12 08:06:42 +0100
commiteb788da3f1af8f506226986f12de6b2b04cdaba1 (patch)
treea2b22fec74c843323bf1876084d69d53e8227448
parentAdd the get_nprocs() function (diff)
downloadgentoo-functions-eb788da3f1af8f506226986f12de6b2b04cdaba1.tar.gz
gentoo-functions-eb788da3f1af8f506226986f12de6b2b04cdaba1.tar.bz2
gentoo-functions-eb788da3f1af8f506226986f12de6b2b04cdaba1.zip
Add the parallel_run() function
Here is an example of how to use it. $ parallel_run 0 sha256sum dir/* Simple commands of a greater level of sophistication can easily be composed with the aid of functions. $ sm3sum() { cksum -a sm3 "$@"; } $ parallel_run 0 sm3sum dir/* Signed-off-by: Kerin Millar <kfm@plushkava.net>
-rw-r--r--functions.sh44
-rwxr-xr-xtest-functions21
2 files changed, 64 insertions, 1 deletions
diff --git a/functions.sh b/functions.sh
index 60a4b2e..e849541 100644
--- a/functions.sh
+++ b/functions.sh
@@ -496,6 +496,50 @@ oldest()
}
#
+# Executes a simple command in parallel. At least two parameters are expected.
+# The first parameter shall be taken as the maximum number of jobs to run
+# concurrently. If specified as less than or equal to 0, the number shall be
+# determined by running the nproc function. The second parameter shall be taken
+# as a command name. The remaining parameters shall be conveyed to the specified
+# command, one at a time. Should at least one command fail, the return value
+# shall be greater than 0.
+#
+parallel_run()
+{
+ local arg cmd i statedir w workers
+
+ if [ "$#" -lt 3 ]; then
+ warn "parallel_run: too few arguments (got $#, expected at least 3)"
+ return 1
+ elif ! is_int "$1"; then
+ _warn_for_args parallel_run "$1"
+ return 1
+ elif [ "$1" -le 0 ] && ! workers=$(get_nprocs); then
+ return 1
+ elif ! statedir=${TMPDIR:-/tmp}/parallel_run.$$.$(srandom); then
+ return 1
+ fi
+ workers=${workers:-$1} cmd=$2
+ shift 2
+ w=0
+ i=0
+ (
+ while [ "$(( w += 1 ))" -le "${workers}" ]; do
+ i=$w
+ while [ "$i" -le "$#" ]; do
+ eval "arg=\$${i}"
+ if ! "${cmd}" "${arg}"; then
+ mkdir -p -- "${statedir}"
+ fi
+ i=$(( i + workers ))
+ done &
+ done
+ wait
+ )
+ ! rmdir -- "${statedir}" 2>/dev/null
+}
+
+#
# Declare the vebegin, veerror, veindent, veinfo, veinfon, veoutdent and vewarn
# functions. These differ from their non-v-prefixed counterparts in that they
# only have an effect where EINFO_VERBOSE is true.
diff --git a/test-functions b/test-functions
index c734141..ed3da42 100755
--- a/test-functions
+++ b/test-functions
@@ -556,6 +556,25 @@ test_get_nprocs() {
iterate_tests 2 "$@"
}
+test_parallel_run() {
+ set -- \
+ ge 1 N/A N/A \
+ eq 0 / N/A \
+ ge 1 /var/empty/nonexistent N/A \
+ eq 0 / / \
+ ge 1 / /var/empty/nonexistent \
+ ge 1 /var/empty/nonexistent /var/empty/nonexistent \
+ ge 1 /var/empty/nonexistent /
+
+ callback() {
+ shift
+ test_description="parallel_run $(_print_args 0 ls "$@")"
+ parallel_run 0 ls "$@" >/dev/null 2>&1
+ }
+
+ iterate_tests 4 "$@"
+}
+
iterate_tests() {
slice_width=$1
shift
@@ -621,7 +640,7 @@ test_newest || rc=1
test_trim || rc=1
test_hr || rc=1
test_whenceforth || rc=1
-test_get_nprocs || rc=1
+test_parallel_run || rc=1
cleanup_tmpdir