我正在shell中编写一个脚本,其中一个命令正在运行并需要2分钟.每次.而且,我们无能为力.但是如果我想在脚本中运行这个命令100次,那么总时间将是200分钟.这将产生一个大问题.没有人想等待200分钟.我想要的是并行运行所有100个命令,以便输出将在2分钟或者可能需要更长时间但不需要200分钟.
如果任何机构可以以任何方式帮助我,我们将不胜感激.
jmd*_*din 14
GNU Parallel是你想要的,除非你想重新发明轮子.这里有一些更详细的例子,但缺点是:
ls | parallel gzip # gzip all files in a directory
Run Code Online (Sandbox Code Playgroud)
P.P*_*.P. 10
...并行运行所有100个命令,以便输出将在2分钟内完成
只有在系统上有200个处理器时才可以执行此操作.
shell脚本中没有这样的实用程序/命令来并行运行命令.你可以做的是在后台运行你的命令:
for ((i=0;i<200;i++))
do
MyCommand &
done
Run Code Online (Sandbox Code Playgroud)
使用&(后台),每个执行都会尽快安排.但这并不能保证您的代码将在200分钟内执行.这取决于您的系统上有多少处理器.
如果你只有一个处理器并且每次执行命令(需要2分钟)正在进行2分钟的计算,那么处理器正在做一些工作,这意味着没有浪费的周期.在这种情况下,并行运行命令并没有帮助,因为只有一个处理器也不是免费的.因此,进程将等待轮到他们执行.
如果您有多个处理器,则上述方法(for循环)可能有助于减少总执行时间.
正如@KingsIndian所说,你可以使用后台任务,这类任务可以让它们并行运行.除此之外,您还可以按进程ID跟踪它们:
#!/bin/bash
# Function to be backgrounded
track() {
sleep $1
printf "\nFinished: %d\n" "$1"
}
start=$(date '+%s')
rand3="$(jot -s\ -r 3 5 10)"
# If you don't have `jot` (*BSD/OSX), substitute your own numbers here.
#rand3="5 8 10"
echo "Random numbers: $rand3"
# Make an associative array in which you'll record pids.
declare -A pids
# Background an instance of the track() function for each number, record the pid.
for n in $rand3; do
track $n &
pid=$!
echo "Backgrounded: $n (pid=$pid)"
pids[$pid]=$n
done
# Watch your stable of backgrounded processes.
# If a pid goes away, remove it from the array.
while [ -n "${pids[*]}" ]; do
sleep 1
for pid in "${!pids[@]}"; do
if ! ps "$pid" >/dev/null; then
unset pids[$pid]
echo "unset: $pid"
fi
done
if [ -z "${!pids[*]}" ]; then
break
fi
printf "\rStill waiting for: %s ... " "${pids[*]}"
done
printf "\r%-25s \n" "Done."
printf "Total runtime: %d seconds\n" "$((`date '+%s'` - $start))"
Run Code Online (Sandbox Code Playgroud)
您还应该查看有关协处理的Bash文档.