【发布时间】:2012-07-19 08:11:13
【问题描述】:
我正在尝试实现简单的并行化,其中命令行分布在不同的进程中。为此,我编写了这个脚本,我将其命名为 jobsel:
(only "#! /bin/bash" and help message is omitted)
slots=$1
sel=$2
[[ $slots -gt 0 ]] || die_usage
[[ $sel -lt $slots ]] || die_usage
i=0
while read line
do
(( i % slots == sel )) && eval $line
i=$(( i + 1 ))
done
# in case the last line does not end with EOL
if [[ $line != "" ]]; then
(( i % slots == sel )) && eval $line
i=$(( i + 1 ))
fi
我输入了eval,因为没有它我无法在命令中使用重定向或管道。
当我在控制台模拟器上像$HOME/util/jobsel 22 0 < cmds 一样运行它时,当cmds 是一个包含echo 0 >> out 之类的行且数量不断增加的文件时,它会按预期在单独的行中输出0, 22, 44...。到目前为止还不错。
所以我把它付诸实践。但是当我通过安全 shell 运行它时,我通过带有背景的at 运行它(每行以& 结束)。然后有一个问题。当我输入 8 行时,启动了 21 个进程! ps -AFH 打印具有相同命令和不同 pID 的进程。所有工作流程都在同一级别,直接在 init 之下。我的程序无论如何都不会创建子进程。
困惑,我通过at 尝试了echo 0 >> out 脚本,然后输出包含重复的行。仍然难以相信,并认为同时追加可能导致异常,我使用其他方法确认某些行运行了多次。
此外,当一切都在终端中运行或我为每个工作进程创建单独的at 作业时,没有这种异常情况。
但这怎么会发生呢?我的脚本有问题吗? at/atd 有问题吗?
【问题讨论】:
-
代替
[[ $(( i % slots )) -eq $sel ]]做(( i % slots == sel ))。请参阅Process Management 和BashFAQ/050。 -
你考虑过使用GNU parallel吗?
-
@DennisWilliamson 谢谢。我正在申请编辑。
-
at在省略最终的&时似乎表现良好。但情况并非总是如此。所以我转向nohups。 -
另外,
((slots > 0 ))和((sel < slots ))
标签: bash process parallel-processing