Linux Bash`wait`命令,等待超过1个PID完成执行
我最近发布了一个问题,问是否有可能 到目前为止,答案似乎是否定的(这很好) 然而,用户为这个问题添加了一个答案,我的问题是关于这个答案的 迭戈回答说 如果您害怕重复使用PID,那么如果您等待 其他答案解释,你可以使用Linux Bash`wait`命令,等待超过1个PID完成执行,linux,bash,wait,pid,Linux,Bash,Wait,Pid,我最近发布了一个问题,问是否有可能 到目前为止,答案似乎是否定的(这很好) 然而,用户为这个问题添加了一个答案,我的问题是关于这个答案的 迭戈回答说 如果您害怕重复使用PID,那么如果您等待 其他答案解释,你可以使用 echo 4194303 > /proc/sys/kernel/pid_max 减少你的恐惧;-) 我真的不明白为什么迭戈在这里用了4194303,但那是另一个问题 我的理解是,我对以下代码有问题: for pid in "${PIDS[@]}" do wait $
echo 4194303 > /proc/sys/kernel/pid_max
减少你的恐惧;-)
我真的不明白为什么迭戈在这里用了4194303,但那是另一个问题
我的理解是,我对以下代码有问题:
for pid in "${PIDS[@]}"
do
wait $pid
done
问题是,我在一个数组中有多个PID,并且for循环将对数组中的每个PID依次运行wait
命令,但是我无法预测进程将按照其PID存储在此数组中的相同顺序完成
ie;可能发生以下情况:
- 开始等待数组索引0中的PID
- 在数组的索引1中具有PID的进程终止
- 新作业在系统上运行,导致存储在PID数组索引1中的PID被重新用于另一个进程
在数组索引0中的PID退出时终止wait
- 开始等待数组索引0中的PID,但现在这是一个不同的过程,我们不知道它是什么
- 重新使用当前正在等待的PID的运行进程从未终止。可能是邮件服务器的PID或系统管理员启动的东西
一直在等待,直到发现下一个严重的linux错误,系统重新启动或断电wait
- 如果是这样,为什么我上面描述的情况不能发生
- 如果是这样,那么今天晚些时候我会发布一个新问题
my_function &
PID="$!"
PIDS+=($PID)
让我们看看你的选择 无条件等待所有后台作业 这样做的好处是简单,但你不能让你的机器忙。如果你想在旧工作完成后开始新工作,你不能。在所有后台作业完成之前,机器的利用率越来越低,此时可以开始新的一批作业 Related是通过将多个参数传递给
wait
来等待作业子集的能力:
unrelated_job &
for i in 1 2 3 4 5; do
cmd & pids+=($!)
done
wait "${pids[@]}" # Does not wait for unrelated_job, though
按任意顺序等待单个作业
这样做的好处是让您在作业完成后进行工作,但是
仍然存在一个问题,即除了$pid
之外的作业可能会首先完成,从而导致机器在$pid
实际完成之前未得到充分利用。但是,您仍然可以获得每个作业的退出状态,即使它在您实际等待它之前完成
等待下一个作业完成(bash
4.3或更高版本)
在这里,您可以等待作业完成,这意味着您可以让您的机器尽可能繁忙。唯一的问题是,如果不使用jobs
获取活动进程列表并将其与pids
进行比较,就不一定知道完成了哪个作业
其他选择?
shell本身并不是进行作业分发的理想平台,这就是为什么设计了大量用于管理批处理作业的程序的原因:
xargs
,并行
,slurm
,qsub
,等等。这是旧的,但是,由于pid冲突,延迟的等待
等待一些随机的不相关进程的场景并没有被直接解决
这在内核级别是不可能的。它的工作方式是,在父进程调用wait(2)
imk_之前,子进程仍然存在。因为子系统仍然存在,linux将耗尽PID,而不是重用它。这有时表现为所谓的僵尸或“不存在”进程——这些是已经退出但尚未被父母“收获”的子进程
现在,在shell级别,您不必调用wait(1)
imk_来获取子进程-bash
会自动执行此操作。我还没有确认,但是当您为一个很久以前退出的子pid运行wait$pid
时,我敢打赌bash
会意识到它已经收获了那个子pid并立即返回信息,而不是等待任何东西
\wait(N)
表示法是一种用于消除API层之间歧义的惯例-N指命令/功能所在的手册部分。在这种情况下,我们有:
:系统调用-请参阅wait(2)
man 2 wait
:shell命令-请参阅wait(1)
或man 1wait
help wait
如果您想知道每个手册部分都有哪些内容,请尝试
man N intro
您是否阅读了bash文档中的wait?它接受多个pid。@BjornA。是的,我有。文档说明它只接受1个PID。引用(my)manbash
:wait[-n][n…]等待每个指定的子进程
wait[-n][n…]等待每个指定的子进程并返回其终止状态。每个n可以是过程ID或作业规范;如果给定了作业规范,则等待该作业管道中的所有进程。如果未给定n,则等待所有当前活动的子进程,返回状态为零。如果提供了-n选项,wait将等待任何作业终止并返回其退出状态。如果n指定一个不存在的进程或作业,则返回状态为
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
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