题
最大限度地占用(I的运行上的东西Debian Lenny t2)我有一个简单的脚本来启动的工作平行:
#!/bin/bash
for i in apache-200901*.log; do echo "Processing $i ..."; do_something_important; done &
for i in apache-200902*.log; do echo "Processing $i ..."; do_something_important; done &
for i in apache-200903*.log; do echo "Processing $i ..."; do_something_important; done &
for i in apache-200904*.log; do echo "Processing $i ..."; do_something_important; done &
...
我很满意这个工作方案,但是我不知道如何写进一步的代码,其中只有执行一旦所有的循环已经完成。
有没有办法得到控制这个吗?
解决方案
有一个bash
内建命令为该。
wait [n ...]
Wait for each specified process and return its termination sta‐
tus. Each n may be a process ID or a job specification; if a
job spec is given, all processes in that job’s pipeline are
waited for. If n is not given, all currently active child pro‐
cesses are waited for, and the return status is zero. If n
specifies a non-existent process or job, the return status is
127. Otherwise, the return status is the exit status of the
last process or job waited for.
其他提示
使用GNU平行会让你的脚本中甚至更短的和可能更加有效:
parallel 'echo "Processing "{}" ..."; do_something_important {}' ::: apache-*.log
这将运行一个工作每CPU核心,并继续做,直到所有文件的处理。
你的解决方案将基本上是分裂该工作组成之前在运行。这里32工作4小组:
GNU平行,而不是产生一个新的进程时,一个完成保留的Cpu活性,从而节省时间:
要了解更多信息:
- 观看视频介绍快速介绍:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
- 走过教程(人parallel_tutorial).你的命令行 会爱上你。
我不得不这样做,最近结束了与以下方案:
while true; do
wait -n || {
code="$?"
([[ $code = "127" ]] && exit 0 || exit "$code")
break
}
done;
在这里,它是如何工作:
wait -n
退出后尽快之一(可能多的)背景的工作退出。它始终的计算结果为真正的和循环下去,直至发生下述任何一种情形:
- 出口码
127
:最后一背景工作成功退出。在 这种情况下,我们忽略的出口码和出口子壳的代码 0. - 任何背景的工作失败。我们只是退出子壳,退出的代码。
与 set -e
, 这将保证该脚本将终止早期,并通过出口码的任何失败的背景工作。
这是我的粗溶液:
function run_task {
cmd=$1
output=$2
concurency=$3
if [ -f ${output}.done ]; then
# experiment already run
echo "Command already run: $cmd. Found output $output"
return
fi
count=`jobs -p | wc -l`
echo "New active task #$count: $cmd > $output"
$cmd > $output && touch $output.done &
stop=$(($count >= $concurency))
while [ $stop -eq 1 ]; do
echo "Waiting for $count worker threads..."
sleep 1
count=`jobs -p | wc -l`
stop=$(($count > $concurency))
done
}
我们的想法是用“工作”,看看有多少孩子都在后台继续运行,等到这个数字下降(孩子退出)。一旦发现孩子存在,接下来的工作就可以开始。
可以看到,还存在一些额外的逻辑,以避免运行相同的实验/命令多次。它确实对我来说工作。然而,这样的逻辑可以是任一跳过或进一步改进(例如,检查文件创建时间戳,输入参数,等)。
不隶属于 StackOverflow