Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux Bash`wait`命令,等待超过1个PID完成执行_Linux_Bash_Wait_Pid - Fatal编程技术网

Linux Bash`wait`命令,等待超过1个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 $

我最近发布了一个问题,问是否有可能

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

然而,用户为这个问题添加了一个答案,我的问题是关于这个答案的

迭戈回答说

如果您害怕重复使用PID,那么如果您等待 其他答案解释,你可以使用

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被重新用于另一个进程
  • wait
    在数组索引0中的PID退出时终止
  • 开始等待数组索引0中的PID,但现在这是一个不同的过程,我们不知道它是什么
  • 重新使用当前正在等待的PID的运行进程从未终止。可能是邮件服务器的PID或系统管理员启动的东西
  • wait
    一直在等待,直到发现下一个严重的linux错误,系统重新启动或断电
迭戈说:

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

ie;我上面描述的情况不可能发生

迭戈说得对吗

  • 如果是这样,为什么我上面描述的情况不能发生
还是迭戈不正确

  • 如果是这样,那么今天晚些时候我会发布一个新问题
附加说明 我突然想到,这个问题可能会令人困惑,除非您知道PID是在后台启动的进程的PID。ie

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
  • wait(1)
    :shell命令-请参阅
    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