我最近发布了一个问题,询问prevent PID's from being re-used是否可能。
到目前为止,答案似乎是否定的。 (可以)
但是,用户Diego Torres Milano添加了该问题的答案,而我的问题是关于该答案的。
迭戈回答,
我实际上不明白为什么迭戈在这里使用了4194303
这个数字,但这是另一个问题。
我的理解是以下代码有问题:
for pid in "${PIDS[@]}"
do
wait $pid
done
问题是我在一个数组中有多个PID,并且for循环将与数组中的每个PID依次运行
wait
命令,但是我无法预测进程将以其PID存储在此顺序的顺序完成大批。IE;可能发生以下情况:
wait
终止,因为数组索引0中的PID退出wait
当前正在等待的PID的运行过程永远不会终止。可能是邮件服务器的PID或系统管理员已启动的东西。 wait
一直等待,直到找到下一个严重的Linux错误并重新启动系统或断电为止迭戈说:
IE;我上面描述的情况不会发生。
迭戈是正确的吗?
还是迭戈不正确?
补充笔记
在我看来,这个问题可能令人困惑,除非您知道PID是后台启动的进程的PID。 IE;
my_function &
PID="$!"
PIDS+=($PID)
最佳答案
让我们来看看您的选择。
无条件等待所有后台作业
for i in 1 2 3 4 5; do
cmd &
done
wait
这具有简单的好处,但是您不能使计算机忙碌。如果要在旧工作完成后开始新工作,则不能。在完成所有后台作业之前,您的机器利用率越来越低,此时您可以开始一批新的作业。
与此相关的是通过将多个参数传递给
wait
来等待一部分作业的能力: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本身并不是进行作业分配的理想平台,这就是为什么要设计许多用于管理批处理作业的程序的原因:
xargs
,parallel
,slurm
,qsub
等。