我需要在尽可能短的时间内运行大量类似的命令并使用所有可用资源。
例如,我的情况是处理图像,当我使用以下命令时:
for INPUT in *.jpg do; some_command; done
该命令被一一执行,并且不使用所有可用资源。
但另一方面,执行for INPUT in *.jpg do; some_command &; done
会使机器在很短的时间内耗尽资源。
我知道 的at
命令batch
,但我不确定是否可以在我的情况下使用它。如果我错了请纠正我。
所以我正在考虑将命令放入某种队列中并立即执行其中的一部分。我不知道如何快速做到这一点,这就是问题所在。我确信以前有人遇到过类似的问题。
请指教。
答案1
GNU Parallel 正是为此而设计的:
parallel some_command {} ::: *.jpg
默认情况下,每个 CPU 核心执行一项作业。在您的情况下,您可能希望比您拥有的核心多运行一项作业:
parallel -j+1 some_command {} ::: *.jpg
GNU Parallel 是一个通用并行器,可以轻松地在同一台计算机或多台您可以通过 ssh 访问的计算机上并行运行作业。
如果您想要在 4 个 CPU 上运行 32 个不同的作业,则并行化的直接方法是在每个 CPU 上运行 8 个作业:
相反,GNU Parallel 在完成后会生成一个新进程 - 保持 CPU 处于活动状态,从而节省时间:
安装
出于安全原因,您应该使用软件包管理器安装 GNU Parallel,但如果 GNU Parallel 未针对您的发行版打包,您可以进行个人安装,这不需要 root 访问权限。这样做可以在 10 秒内完成:
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash
对于其他安装选项,请参阅http://git.savannah.gnu.org/cgit/parallel.git/tree/README
了解更多
查看更多示例:http://www.gnu.org/software/parallel/man.html
观看介绍视频:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
浏览本教程:http://www.gnu.org/software/parallel/parallel_tutorial.html
注册电子邮件列表以获得支持:https://lists.gnu.org/mailman/listinfo/parallel
答案2
您可以使用 GNU make 并--jobs
选择并行运行,但仅限于指定的作业数量。您可以将该数字调整为不会杀死您的机器的值。
这是一个示例 Makefile,它使用目标 ah(这些可能是您的输出文件,例如)并为每个目标运行一组(虚拟)命令:
all: a b c d e f g h
a b c d e f g h:
echo $@; sleep 10
注意命令的缩进必须是一个 TAB 字符。请参阅GNU make 文档有关 Makefile 语法的详细信息。
您可以调用 makemake --jobs 4
并获得以下输出(我time make --jobs 4
在下面使用它来显示经过的时间):
echo a; sleep 10
echo b; sleep 10
echo c; sleep 10
echo d; sleep 10
b
a
c
d
echo e; sleep 10
echo f; sleep 10
echo g; sleep 10
e
f
echo h; sleep 10
g
h
real 0m20.009s
user 0m0.010s
sys 0m0.011s
前四个并行执行,然后是接下来的四个,因此总耗时为 20 秒。