Skip to content

Instantly share code, notes, and snippets.

@piersy
Last active March 19, 2016 16:25
Show Gist options
  • Save piersy/e6f6c8b907437a66726e to your computer and use it in GitHub Desktop.
Save piersy/e6f6c8b907437a66726e to your computer and use it in GitHub Desktop.
Throttling asynchronous processes in bash
#!/bin/bash
#Fail fast on errors
set -euo pipefail
# Arguments
# $1 -> throttlerName
# Initializes a throttler of the given name
initThrottler(){
rm $1 2>/dev/null|| true
mkfifo $1
exec 3<> $1
}
# Arguments
# $1 -> limit
# $2 -> throttlerName
# Called before running any processes
# Will wait while the current number of running processes
# exceed the given limit
throttle(){
local limit=$1
local throttlerName=$2
#We generate a counter name here so that
#Different throttler's counts dont interact with
#each other. This makes the access of the variable
#a little tricky.
local counterName=${throttlerName}Counter
if [[ -z ${!counterName:-} ]]; then
eval "$counterName=0"
fi
eval "$counterName=$((${counterName}+1))"
if [[ ${!counterName} > $limit ]]; then
while read line < $throttlerName; do
echo $line
eval "$counterName=$((${counterName}-1))"
if [[ ${!counterName} -le $limit ]]; then
break
fi
done
fi
}
#Usage below
randomLongProcess(){
sleep $((RANDOM % 10))
echo fin > $throttlerName
}
throttlerName=testThrottler
initThrottler $throttlerName
for x in {1..10}; do
#Call throttle first
throttle 3 $throttlerName
#echo Update
echo Process number $x
#Start background process
randomLongProcess &
done
wait
@piersy
Copy link
Author

piersy commented Mar 19, 2016

This was useful to me for multithreading builds while not totally overloading my machine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment