我想在 ~6500 个目录中运行一个简单的 python 脚本。最简单且效率最低的方法是:
for d in *_directorynumber; do (cd "$d" && cp ../script.py . && python ./script.py );done
这显然需要永远。相反,我尝试并行运行:
task(){
cd "$d" && python ./script.py .
}
然后按如下方式运行此任务:
for d in *_directorynumber; do
task "$d" &
done
大约运行 500 次后,我收到以下错误:
-bash: fork: retry: Resource temporarily unavailable
-bash: fork: retry: No child processes
-bash: fork: retry: No child processes
-bash: fork: retry: No child processes
还有其他并行化方法吗?
答案1
进程数量有限制。您可以使用命令显示它ulimit -u
。您可以使用相同的命令来增加它。如果它是共享计算机,您可能没有执行此操作的权限。
并行运行 6500 个进程很可能是一个坏主意。
- 您需要 RAM 用于 6500 个进程。
- 如果你的任务受 CPU 限制,它会变慢,因为它需要更多的上下文切换。
- 如果您的任务受 I/O 限制,那么有 6500 个进程访问不同的目录也会使其变慢。
您的任务可能会受益于某些并行进程,但您应该将其限制为您拥有的 CPU 核心数量的一小部分。
答案2
尝试:
parallel 'cd {} && cp ../script.py . && python ./script.py' ::: *_directorynumber
这将为script.py
每个 CPU 线程运行一个,直到所有操作完成。
如果script.py
不受 CPU 限制,您可以使用以下命令调整作业数量--jobs
:
--jobs 10
正好并行运行 10 个--jobs 200%
并行运行 2x CPU 线程--jobs 0
尽可能多地运行,直到达到限制(例如:),-bash: fork: retry: No child processes
然后保持在该限制以下。