我需要限制并行执行的进程数。例如,我想执行这个伪命令行:
export POOL_PARALLELISM=4
for i in `seq 100` ; do
pool foo -bar &
done
pool foo -bar # would not complete until the first 100 finished.
因此,尽管101 foo
排队等待运行,但在任何给定时间只会运行4 pool
。 at
会fork()/ exit()并将剩余的进程排队直到完成。
使用Unix工具有一个简单的机制吗? batch
和{{1}}不适用,因为它们通常会在分钟时调用以及按顺序执行作业。使用队列不一定是最好的,因为我希望这些同步。
在我编写使用信号量和共享内存的C包装器然后调试我肯定会介绍的死锁之前,任何人都可以推荐使用bash / shell或其他工具机制来完成此任务。
答案 0 :(得分:4)
绝对没有必要自己编写这个工具,有几个不错的选择。
make
make
可以很容易地做到这一点,但它确实广泛依赖文件来推动这个过程。 (如果要对生成输出文件的每个输入文件运行某些操作,这可能很棒。)-j
命令行选项将运行指定数量的任务和-l
负载平均值命令行选项将指定在启动新任务之前必须满足的系统负载平均值。 (如果你想在后台做一些工作,这可能会很好。不要忘记nice(1)
命令,这也可以在这里帮助。)
因此,图像转换的快速(未经测试)Makefile
:
ALL=$(patsubst cimg%.jpg,thumb_cimg%.jpg,$(wildcard *.jpg))
.PHONY: all
all: $(ALL)
convert $< -resize 100x100 $@
如果您使用make
运行它,它将一次运行一次。如果您使用make -j8
运行,它将运行八个单独的作业。如果你运行make -j
,它将启动数百个。 (在编译源代码时,我发现核心数量的两倍是一个很好的起点。这样可以在等待磁盘IO请求时为每个处理器做些事情。不同的机器和不同的负载可能会有不同的工作方式。)
xargs
xargs
提供--max-procs
命令行选项。如果可以使用ascii NUL
分隔的输入命令或新行分隔的输入命令,基于单个输入流将并行进程分开,则这是最好的。 (好吧,-d
选项可以让你选择别的东西,但是这两个很常见且容易。)这样你就可以使用find(1)
强大的文件选择语法,而不是编写像上面的Makefile
示例,或者让您的输入与文件完全无关。 (考虑一下你是否有一个程序来计算素数因子中的大型复合数字 - 使该任务适合make
最多只是尴尬。xargs
可以很容易地做到。)
前面的示例可能如下所示:
find . -name '*jpg' -print0 | xargs -0 --max-procs 16 -I {} convert {} --resize 100x100 thumb_{}
parallel
moreutils
包(至少在Ubuntu上可用)提供parallel
命令。它可以以两种不同的方式运行:在不同的参数上运行指定的命令,或者并行运行不同的命令。上一个示例可能如下所示:
parallel -i -j 16 convert {} -resize 100x100 thumb_{} -- *.jpg
beanstalkd
beanstalkd
程序采用完全不同的方法:它提供消息总线,供您向输入的作业提交请求,作业服务器阻止,执行作业,然后返回等待队列中的新作业。如果要将数据写回发起作业的特定HTTP请求,这可能不是很方便,因为您必须自己提供该机制(可能是beanstalkd
服务器上的另一个'管'),但是如果最终结果是将数据提交到数据库,电子邮件或类似异步的东西,这可能是最容易集成到现有应用程序中的。