From f437c8d7e29a0df4fe77768085d697a72ac461c3 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Wed, 10 Aug 2016 13:41:33 +0200 Subject: [PATCH] background sub-process limiter --- bash_multithread.sh | 84 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100755 bash_multithread.sh diff --git a/bash_multithread.sh b/bash_multithread.sh new file mode 100755 index 0000000000..6006b95b1c --- /dev/null +++ b/bash_multithread.sh @@ -0,0 +1,84 @@ +#!/bin/bash + +# slightly modified implementation of sub-process limiter +# by paxdiablo. See http://stackoverflow.com/a/1685440 + +# bgxupdate - update active processes in a group. +# Works by transferring each process to new group +# if it is still active. +# in: bgxgrp - current group of processes. +# out: bgxgrp - new group of processes. +# out: bgxcount - number of processes in new group. + +bgxupdate() { + bgxoldgrp=${bgxgrp} + bgxgrp="" + ((bgxcount = 0)) + bgxjobs=" $(jobs -pr | tr '\n' ' ')" + for bgxpid in ${bgxoldgrp} ; do + echo "${bgxjobs}" | grep " ${bgxpid} " >/dev/null 2>&1 + if [[ $? -eq 0 ]] ; then + bgxgrp="${bgxgrp} ${bgxpid}" + ((bgxcount = bgxcount + 1)) + fi + done +} + +# bgxlimit - start a sub-process with a limit. +# Loops, calling bgxupdate until there is a free +# slot to run another sub-process. Then runs it +# an updates the process group. +# in: $1 - the limit on processes. +# in: $2+ - the command to run for new process. +# in: bgxgrp - the current group of processes. +# out: bgxgrp - new group of processes + +bgxlimit() { + bgxmax=$1 ; shift + bgxupdate + while [[ ${bgxcount} -ge ${bgxmax} ]] ; do + sleep 0.1 + bgxupdate + done + if [[ "$1" != "-" ]] ; then + "$@" & + bgxgrp="${bgxgrp} $!" + fi + # echo '[' ${bgxgrp} ']' +} + +# bgxwait - wait for sub-processes to finish +# Loops calling bgxupdate until there is something +# in a process group + +bgxwait() { + bgxupdate + while [[ ${bgxcount} -ne 0 ]] ; do + oldcount=${bgxcount} + while [[ ${oldcount} -eq ${bgxcount} ]] ; do + sleep 0.1 + bgxupdate + done + # echo '[' ${bgxgrp} ']' + done +} + +bgxtest() { + callback() { + id=$1 ; shift + echo start $id $(date | awk '{print $4}') "$BASHPID" + sleep ${id}0 + echo end $id $(date | awk '{print $4}') "$BASHPID" + } + + # Test program, create group and run 6 sleeps with + # limit of 3. + + bgxgrp="" + for i in 1 2 3 4 5 6 ; do + bgxlimit 3 callback ${i} + done + + # Wait until all others are finished. + bgxwait; +} -- GitLab