等待MacOS上的任何儿童进程退出?
我想知道如何在 macOS 中等待任何进程完成,因为 wait -n
不起作用。我有一个脚本在做几件事,在某些时候它会进入一个循环,在后台调用另一个脚本来利用一些并行性,但不会超过 X 次,因为它效率不高。因此,我需要等待任何子进程完成才能创建新进程。
我见过这个问题,但它没有不回答“任何”部分,它只是说明如何等待特定进程完成。
我曾考虑过存储所有 PID 并主动检查它们是否仍在使用 ps
运行,但这非常草率且消耗资源。我还考虑过将 bash 升级到较新的版本(如果这在 macOS 中可能实现,而又不会破坏 bash 已有的工作方式),但如果没有其他方法来实际等待任何进程,我会非常失望最后,这是一个基本功能...有什么想法吗?
我的代码的基本版本如下所示:
for vid_file in $VID_FILES
do
my_script.sh $vid_file other_args &
((TOTAL_PROCESSES=TOTAL_PROCESSES+1))
if [ $TOTAL_PROCESSES -ge $MAX_PROCESS ]; then
wait -n
((TOTAL_PROCESSES=TOTAL_PROCESSES-1))
fi
done
我既不优雅也不高效的方法来替代 wait -n
:
NUM_PROCC=$MAX_PROCESS
while [ $NUM_PROCC -ge $MAX_PROCESS ]
do
sleep 5
NUM_PROCC=$(ps | grep "my_script.sh"| wc -l | tr -d " \t")
# grep command will count as one so we need to remove it
((NUM_PROCC=NUM_PROCC-1))
done
PS:这个问题可以关闭并与我上面提到的问题合并。我刚刚创建了这个新的,因为 stackoverflow 不允许我发表评论或询问...
PS2:我确实明白我的目标可以通过其他方式实现。如果您没有特定问题本身的答案,而是有解决方法,请让其他人回答有关“等待任何”的问题,因为这对我/每个人将来也非常有用。我当然也会欢迎并感谢您的解决方法!
先感谢您!
I am wondering how to wait for any process to finish in macOS, since wait -n
doesn't work. I have a script doing several things, and in some point it will enter a loop calling another script to the background to exploit some parallelism, but not more than X times since it wouldn't be efficient. Thus, I need to wait for any child process to finish before creating new processes.
I have seen this question but it doesn't answer the "any" part, it just says how to wait to a specific process to finish.
I've thought of either storing all PIDs and actively checking if they're still running with ps
, but it's very slapdash and resource consuming. I also thought about upgrading bash to a newer version (if that's ever possible in macOS without breaking how bash already works), but I would be very disappointed if there was no other way to actually wait for any process to finish, it's such a basic feature... Any ideas?
A basic version of my code would look like this:
for vid_file in $VID_FILES
do
my_script.sh $vid_file other_args &
((TOTAL_PROCESSES=TOTAL_PROCESSES+1))
if [ $TOTAL_PROCESSES -ge $MAX_PROCESS ]; then
wait -n
((TOTAL_PROCESSES=TOTAL_PROCESSES-1))
fi
done
My neither elegant nor performant approach to substitute the wait -n
:
NUM_PROCC=$MAX_PROCESS
while [ $NUM_PROCC -ge $MAX_PROCESS ]
do
sleep 5
NUM_PROCC=$(ps | grep "my_script.sh"| wc -l | tr -d " \t")
# grep command will count as one so we need to remove it
((NUM_PROCC=NUM_PROCC-1))
done
PS: This question could be closed and merged with the one I mentioned above. I've just created this new one because stackoverflow wouldn't let me comment or ask...
PS2: I do understand that my objective could be achieved by other means. If you don't have an answer for the specific question itself but rather a workaround, please let other people answer the question about "waiting any" since it would be very useful for me/everyone in the future as well. I will of course welcome and be thankful for the workaround too!
Thank you in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
看起来您只是想限制同时运行的进程数量。这是使用
bash <= 4.2
执行此操作的基本方法:这是
bash >= 4.3
版本:It seems like you just want to limit the number of processes that are running at the same time. Here's a rudimentary way to do it with
bash <= 4.2
:Here's the
bash >= 4.3
version:GNU make 具有并行化功能,并且以下 Makefile 甚至可以与 macOS 附带的非常旧的 make 3.81 一起使用。将
my_script.sh
之前的 4 个前导空格替换为制表符,并将其存储在名为Makefile
的文件中:然后最多并行运行 8 个作业:
Make 可以做得更好:避免重做已经完成的事情:
在最后一个版本中,会为每个处理的视频
foo
创建一个空标记文件.foo.done
。如果稍后您重新运行 make 并且视频foo
没有改变,则不会重新处理。输入make clean
以删除所有标记文件。不要忘记用制表符替换前导空格。GNU make has parallelization capabilities and the following Makefile should work even with the very old make 3.81 that comes with macOS. Replace the 4 leading spaces before
my_script.sh
by a tab and store this in a file namedMakefile
:And then to run 8 jobs max in parallel:
Make can do even better: avoid redoing things that have already been done:
With this last version an empty tag file
.foo.done
is created for each processed videofoo
. If, later, you re-run make and videofoo
did not change, it will not be re-processed. Typemake clean
to delete all tag files. Do not forget to replace the leading spaces by a tab.建议 1:完成指示文件
建议将任务完成指示文件添加到您的
my_script.sh
中,如下所示:
在您的部署脚本中测试完成指示文件是否存在。
不要忘记清理完成指示器文件。
此方法的优点:
此方法的缺点:
my_script.sh
建议2:将
wait
命令与pgrep
命令结合使用建议详细了解
wait
命令此处。建议在此处了解有关
pgrep
命令的更多信息。这种方法的优点:
这种方法的缺点:
wait
命令是特定于 Linuxbash
的,也许在其他 shell 中也是如此。检查您当前的支持。Suggestion 1: Completion indicator file
Suggesting to add task completion indication file to your
my_script.sh
Like this:
And in your deployment script test if the completion indicator file exist.
Don't forget to clean up the completion indicator files.
Advantages for this approach:
Disadvantages for this approach:
my_script.sh
Suggestion 2: Using
wait
command withpgrep
commandSuggesting to learn more about
wait
command here.Suggesting to learn more about
pgrep
command here.Advantages for this approach:
Disadvantages for this approach:
wait
command is specific to Linuxbash
maybe in other shells as well. Check your current support.使用GNU平行,它看起来像:
With GNU Parallel it would look something like: