Shell脚本中的并行处理或线程

Pri*_*arg 10 unix shell

我正在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循环)可能有助于减少总执行时间.


gho*_*oti 5

正如@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文档.