【问题标题】:Shell script: Wait for any process in a group to finishShell 脚本:等待组中的任何进程完成
【发布时间】:2020-07-16 14:47:39
【问题描述】:

我有一个(小)列表,其中包含我需要提交给 linux 上的 slurm 的 n 个脚本。每个脚本都会做一些工作,然后将输出写入文件。当我请求 32 个内核时,每个脚本的工作部分的执行速度比我请求 16 个或(更糟的)8 个内核时要快得多;但是,调度的等待时间通常最高的是 32 个核心,然后是 16 个,然后是 8 个。根据我无法控制的影响等待时间的条件,请求 32 个核心可能会导致总时间最短,也可能不会。

我的解决方案是提交 n*3 个作业,每个脚本和 {32、16、8} 中的每个处理器数量一个。对于每个脚本,我只需要完成一个过程,我不在乎它是什么。到目前为止,我手动检查每个进程的输出是否已完成,然后手动取消运行相同脚本的其他两个进程。我想自动化这个。

如何同时运行 n 组进程,等待每个组中的第一个进程完成(此时,应该取消组中的其他进程),并等待所有组都发生这种情况在继续脚本中的其他命令之前?

我目前提交工作的代码是:

for i in {1..9};
    do for p in 32 16 8;
        do srun -t 3:00:00 -N 1 -n 1 -c $p --mem=50g python my_script_$i.py $p > my_script_${i}_${p}.out &
        done;
    done;
wait

我查看了等待命令,但我不确定如何等待任何进程(而不是所有进程或特定进程)完成。

我也接受这样的可能性,即有更好的方法将这些作业提交给 slurm,而不是使用 srun 循环——我是 slurm 初学者。

编辑:https://stackoverflow.com/a/41613532/10499953 可能是相关的,但我不确定如何使其并行工作。

【问题讨论】:

  • bash 4.3 为wait 引入了一个-n 选项,该选项将一直阻塞,直到任何人后台作业完成。

标签: bash shell slurm


【解决方案1】:

在子shell(在后台)中运行每个组,以便wait -n 可以等待该组中的作业完成。

for i in {1..9}; do
  ( for p in 32 16 8; do
      srun ... & jobs+=($!)
    done
    wait -n  "${jobs[@]}" # Wait for one of the preceding 3 jobs to complete
    kill "${jobs[@]}"     # Kill the other two
  ) &
done

wait  # Wait for each of the 9 groups to complete

【讨论】:

  • 这很好,但我发现我正在运行它的 RHEL 7.7 集群使用 bash 4.2.46。有时我可以在没有管理员权限的情况下在我的主目录中安装软件包,但由于某种原因似乎很难获得 bash 4.3。有没有不依赖 bash 4.3 的解决方案?
  • 我能够从源代码构建一个更新的 bash,它似乎正在工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-17
  • 1970-01-01
  • 1970-01-01
  • 2016-05-23
  • 2011-03-19
  • 1970-01-01
相关资源
最近更新 更多