Bash等待命令,等待超过1个PID完成执行

我最近发表了一个问题,问是否有可能阻止PID被重新使用 。

到目前为止答案似乎是否定的。 (这很好。)

然而,用户迭戈·托雷斯·米兰(Diego Torres Milano)给这个问题添了一个答案,我的问题就是这个问题。

迭戈回答说,

如果你害怕重复使用PID,如果你等待其他答案的解释就不会发生,你可以使用

echo 4194303 > /proc/sys/kernel/pid_max 

减less你的恐惧;-)

我不明白为什么迭戈在这里使用了4194303号码,但这是另一个问题。

我的理解是,我遇到了以下代码的问题:

 for pid in "${PIDS[@]}" do wait $pid done 

问题是,我有一个数组中的多个PID,并且for循环将依次运行数组中的每个PID的wait命令,但是我无法预测这些进程将按照它们的PID存储在这个arrays。

即; 可能会发生以下情况:

  • 开始等待数组索引0中的PID
  • 数组索引1中的PID进程终止
  • 新作业在系统上运行,导致存储在PID数组索引1中的PID被重新用于另一个进程
  • wait终止,因为数组索引0中的PID退出
  • 开始在数组索引0中等待PID, 除了这是一个不同的过程,我们不知道它是什么
  • 重新使用目前正在等待的PID的运行过程永远不会终止。 也许这是邮件服务器的PID或系统pipe理员已经启动的东西。
  • 等待,直到发现下一个严重的Linux错误,系统重新启动或停电

迭戈说:

这不会发生,如果你等待其他答案的解释

即; 我上面所描述的情况是不可能发生的。

迭戈是否正确?

  • 如果是这样,为什么我上面描述的情况不会发生?

或者迭戈不正确?

  • 如果是的话,那么今天晚些时候我会发布一个新的问题。

补充笔记

对我来说,这个问题可能会令人困惑,除非你知道PID是在后台启动的进程的PID。 即;

 my_function & PID="$!" PIDS+=($PID) 

让我们来看看你的选择。

无条件等待所有后台工作

 for i in 1 2 3 4 5; do cmd & done wait 

这有一个简单的好处,但你不能让你的机器忙碌。 如果你想像旧的一样完成新的工作,你就不能。 在所有后台作业完成之前,您的机器使用越来越少,在此时您可以开始新的一批作业。

相关的是通过传递多个参数waitwait作业子集的能力:

 unrelated_job & for i in 1 2 3 4 5; do cmd & pids+=($!) done wait "${pids[@]}" # Does not wait for unrelated_job, though 

以任意顺序等待个人工作

 for i in 1 2 3 4 5; do cmd & pids+=($!) done for pid in "${pids[@]}"; do wait "$pid" # do something when a job completes done 

这有利于让你在工作完成后继续工作,但是仍然有一个问题:除了$pid可能会先完成,让你的机器利用不足,直到$pid实际完成。 但是,即使在您实际等待之前完成,您仍然可以获得每个单独作业的退出状态。

等待下一个工作完成( bash 4.3或更高版本)

 for i in 1 2 3 4 5; do cmd & pids+=($!) done for pid in "${pids[@]}"; do wait -n # do something when a job completes done 

在这里,您可以等到作业完成,这意味着您可以尽可能保持机器的繁忙。 唯一的问题是,你不一定知道哪个工作完成,没有使用jobs来获得活动进程列表,并将其与pids进行比较。

其他选项?

shell本身并不是一个理想的工作分配平台,这就是为什么有许多用于管理批处理作业的程序: xargsparallelslurmqsub等等。