shell 脚本中的并行处理,“pid 不是此 shell 的子进程”

发布于 2024-12-14 04:05:38 字数 1274 浏览 2 评论 0原文

我有一个关于 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
Program
, which I wish to run multiple times, in a loop within a loop. This program is basically this:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

许仙没带伞 2024-12-21 04:05:38

() 调用一个子 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).

浮光之海 2024-12-21 04:05:38

您可能会发现 GNU Parallel 很有用。

parallel -j+0 ./myProgram ::: $MYPATH/$SUBDIRS/*

这将并行运行与 ./myProgram 一样多的 CPU 内核。

You may find GNU Parallel useful.

parallel -j+0 ./myProgram ::: $MYPATH/$SUBDIRS/*

This will run as many as ./myProgram as CPU cores in parallel.

标点 2024-12-21 04:05:38

要等待非子进程,您可以观察 proc 文件系统,

while [ -e /proc/$pid ]; do sleep 1; done

如果 pid 进程终止,这可能会产生误报
并且另一个进程立即采用相同的 pid

修复:还要检查进程启动时间

_wait() {
  # wait for non-child process
  local pid=$1
  # process start time
  local pst=$(stat -c%X /proc/$pid 2>/dev/null || true)
  [ -z "$pst" ] && return
  while [ "$(stat -c%X /proc/$pid 2>/dev/null || true)" == $pst ]; do sleep 1; done
}

_wait 12345

to wait for a non-child process, you can watch the proc filesystem

while [ -e /proc/$pid ]; do sleep 1; done

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

_wait() {
  # wait for non-child process
  local pid=$1
  # process start time
  local pst=$(stat -c%X /proc/$pid 2>/dev/null || true)
  [ -z "$pst" ] && return
  while [ "$(stat -c%X /proc/$pid 2>/dev/null || true)" == $pst ]; do sleep 1; done
}

_wait 12345
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文