shell 脚本中的并行处理,“pid 不是此 shell 的子进程”
我有一个关于 shell 脚本并行处理的问题。我有一个程序我的 程序
,我希望在循环中循环运行多次。该程序基本上是这样的:
MYPATHDIR=`ls $MYPATH`
for SUBDIRS in $MYPATHDIR; do
SUBDIR_FILES=`ls $MYPATH/$SUBDIRS`
for SUBSUBDIRS in $SUBDIR_FILES; do
find $MYPATH/$SUBDIRS/$SUBSUBDIRS | ./myProgram $MYPATH/$SUBDIRS/outputfile.dat
done
done
我想做的是利用并行处理。因此,我尝试在中间行中立即启动所有 myPrograms
:
(find $MYPATH/$SUBDIRS/$SUBSUBDIRS | ./myProgram $MYPATH/$SUBDIRS/outputfile.dat &)
但是,这同时开始了对 myProgram
的所有 300 个左右的调用,导致 RAM 问题等
。想要做的是并行运行内部循环中每次出现的 myProgram
,但要等待所有这些完成,然后再继续下一个外部循环迭代。基于这个问题的答案< /a>,我尝试了以下操作:
for SUBDIRS in $MYPATHDIR; do
SUBDIR_FILES=`ls $MYPATH/$SUBDIRS`
for SUBSUBDIRS in $SUBDIR_FILES; do
(find $MYPATH/$SUBDIRS/$SUBSUBDIRS | ./myProgram $MYPATH/$SUBDIRS/outputfile.dat &)
done
wait $(pgrep myProgram)
done
但我收到以下警告/错误,重复多次:
./myScript.sh: line 30: wait: pid 1133 is not a child of this shell
...并且所有 myPrograms
都像以前一样立即启动。
我做错了什么?我可以做什么来实现我的目标?谢谢。
I have a question about parallel processing in shell scripting. I have a program my
, which I wish to run multiple times, in a loop within a loop. This program is basically this:
Program
MYPATHDIR=`ls $MYPATH`
for SUBDIRS in $MYPATHDIR; do
SUBDIR_FILES=`ls $MYPATH/$SUBDIRS`
for SUBSUBDIRS in $SUBDIR_FILES; do
find $MYPATH/$SUBDIRS/$SUBSUBDIRS | ./myProgram $MYPATH/$SUBDIRS/outputfile.dat
done
done
What I wish to do is to take advantage of parallel processing. So I tried this for the middle line to start all the myPrograms
at once:
(find $MYPATH/$SUBDIRS/$SUBSUBDIRS | ./myProgram $MYPATH/$SUBDIRS/outputfile.dat &)
However, this began all 300 or so calls to myProgram
simultaneously, causing RAM issues etc.
What I would like to do is to run each occurrence of myProgram
in the inner loop in parallel, but wait for all of these to finish before moving on to the next outer loop iteration. Based on the answers to this question, I tried the following:
for SUBDIRS in $MYPATHDIR; do
SUBDIR_FILES=`ls $MYPATH/$SUBDIRS`
for SUBSUBDIRS in $SUBDIR_FILES; do
(find $MYPATH/$SUBDIRS/$SUBSUBDIRS | ./myProgram $MYPATH/$SUBDIRS/outputfile.dat &)
done
wait $(pgrep myProgram)
done
But I got the following warning/error, repeated multiple times:
./myScript.sh: line 30: wait: pid 1133 is not a child of this shell
...and all the myPrograms
were started at once, as before.
What am I doing wrong? What can I do to achieve my aims? Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
()
调用一个子 shell,然后该子 shell 调用 find/myprogram,因此您正在处理“孙子”进程。你不能侍候孙子,只能侍候直系后裔(又名孩子)。()
invokes a subshell, which then invokes find/myprogram, so you're dealing with "grandchildren" processes. You can't wait on grandchildren, only direct descendants (aka children).您可能会发现 GNU Parallel 很有用。
这将并行运行与
./myProgram
一样多的 CPU 内核。You may find GNU Parallel useful.
This will run as many as
./myProgram
as CPU cores in parallel.要等待非子进程,您可以观察 proc 文件系统,
如果 pid 进程终止,这可能会产生误报
并且另一个进程立即采用相同的 pid
修复:还要检查进程启动时间
to wait for a non-child process, you can watch the proc filesystem
this can produce false positives if the pid process terminates
and another process immediately takes the same pid
fix: also check the process start time