1.8 进程与后台

这里主要讲的是 Linux 下的“任务管理器(Windows)”,查看任务进程,资源占用,杀任务进程...以及如何将任务挂到后台以及集群队列的使用。

1. 进程、后台

bash
ps -ef | grep python # 查看和 python 相关的进程
top                  # 一个系统资源面板,类似 Windows 任务管理器
kill 12345           # 终止进程号 (pid)  12345 的进程
pkill python         # 杀掉所有 python 进程
jobs                 # 查看当前 shell 的后台任务

可以先把它们粗略理解成:

  • ps:查进程在不在
  • top:看资源占用和系统状态
  • kill / pkill:结束进程
  • jobs:看当前 shell 里挂到后台的任务

jobs 只能看当前 shell 启动的后台任务。

如果你重新登录了服务器,通常还是要靠 ps 去找旧进程。

2. 将任务挂在后台

我们是通过 ssh 连接服务器,如果我们关闭 ssh 连接,那么我们的任务将会被中断,也许有些时间你想让服务器一直运行你的任务。

这里提供2种思路:

  • nohup ... &
  • tmux

2.1 nohup&

这是最简单的一种用法。

bash
nohup python train.py > run.log 2>&1 & # 把任务挂到后台并写日志

可以先这样理解:

  • nohup:退出终端后程序尽量继续运行,这个起到让任务不断
  • > run.log:把标准输出写到日志
  • 2>&1:把报错也写进同一个日志
  • &:让命令在后台运行,这个是放到后台,而不是占用当前的 ssh 窗口

启动之后常见检查方式:

bash
tail -f run.log        # 实时看日志
ps -ef | grep train.py # 查进程是否还在

另外,这里的 2>&1 值得单独解释一下,因为你以后会经常见到。

在 shell 里,可以先这样理解:

  • 1:标准输出 stdout
  • 2:标准错误 stderr

很多程序运行时,正常打印的内容会走标准输出,报错信息会走标准错误。

所以:

bash
python train.py > run.log

这条命令只会把正常输出写进 run.log,但报错信息仍然会直接出现在终端里。

简单点, 2>&1 的目的就是让报错也跟着正常输出走,最后写到同一个地方。

2.2 tmux

bash
tmux new -s work # 创建一个名为 work  tmux 会话
python train.py  #  tmux 会话里运行任务

暂时离开会话:

text
Ctrl-b d

重新接回去:

bash
tmux ls          # 查看当前已有的 tmux 会话
tmux attach -t work # 重新连接名为 work 的会话

tmux 是很强大的命令,可以分屏。请你去问 LLM 吧,这里我就不展开了。

3 集群调度系统

3.1 集群基础与使用边界

由于科学计算实际是计算密集型的任务,稍微复杂一点的计算,个人电脑可能要跑几天几夜,甚至根本跑不了(OOM)。 因此,实际上我们大部分的科学计算任务都是在更强的集群上跑的,集群简单理解就是性能更强的很多电脑连在一起。

集群算力更强,同时它是多人共享的计算资源,这里跟之前的 1.6 权限闭环了。 在使用时,你通常先登录到 login node,在那里改文件、整理目录、提交任务;真正的大计算会被调度系统送到 compute node 即另一台电脑上运行。

所以使用集群计算任务并不是直接在计算节点执行命令,而是“提交一个作业”。 这个作业会告诉系统:我要跑什么程序、需要多少核、最多跑多久、输出日志写到哪里。 下面先用 Slurm 队列讲清楚这件事,再扩展到其他队列 PBSLSF

3.2 使用 Slurm 提交作业

Slurm 是现在很常见的集群调度系统。如果一台机器使用 Slurm,你通常不会在登录节点上直接运行:

bash
vasp_std

而是写一个作业脚本,比如 run.slurm

bash
#!/bin/bash
#SBATCH -J test-job
#SBATCH -p cpu
#SBATCH -N 1
#SBATCH -n 16
#SBATCH --time=12:00:00
#SBATCH -o slurm-%j.out

cd $SLURM_SUBMIT_DIR
srun vasp_std

这个脚本可以先粗略理解成两部分。前面那些 #SBATCH 行是在向集群申请资源,后面的普通 shell 命令才是真正要执行的计算流程。

几个最常见的参数先记住这些就够了:

  • #SBATCH -J:作业名
  • #SBATCH -p:分区或队列
  • #SBATCH -N:节点数
  • #SBATCH -n:总核数或总任务数
  • #SBATCH --time:最长运行时间
  • #SBATCH -o:标准输出日志文件

提交作业

真正提交时,在登录节点运行:

bash
sbatch run.slurm

提交成功后,Slurm 通常会返回一个 job id:

text
Submitted batch job 123456

这个 123456 很重要。之后查任务、取消任务、看日志,都会用到它。

查看、取消和看日志

提交之后,第一件事通常是看队列:

bash
squeue -u $USER

如果任务显示 PD,说明还在排队;如果显示 R,说明已经在运行。

常见状态可以这样看:

  • PD:pending,排队中
  • R:running,运行中
  • CG:completing,快结束了
  • CD:completed,正常完成
  • F:failed,失败

如果发现脚本写错了,或者资源申请不合理,可以取消任务:

bash
scancel 123456

3.3 PBS / qsub 怎么对应

所有的集群管理系统的逻辑大同小异只是在具体命令细节上有差别。

有些集群不用 Slurm,而是用 PBS。这时你会看到的命令通常是:

  • qsub:提交任务
  • qstat:查看任务
  • qdel:删除任务

一个最小 PBS 脚本大概长这样:

bash
#!/bin/bash
#PBS -N test-job
#PBS -q batch
#PBS -l nodes=1:ppn=16
#PBS -l walltime=12:00:00
#PBS -o pbs.out

cd $PBS_O_WORKDIR
module load vasp
mpirun vasp_std

提交任务:

bash
qsub run.pbs

查看自己的任务:

bash
qstat -u $USER

删除任务:

bash
qdel 123456

3.4 LSF 怎么对应

还有一些集群会用 LSF。它常见的三个命令是:

  • bsub:提交任务
  • bjobs:查看任务
  • bkill:删除任务

查看任务:

bash
bjobs

删除任务:

bash
bkill 123456

3.5 三种系统的最小对照

如果把三套系统放在一起看,最小对应关系是:

功能SlurmPBS/TorqueLSF
提交任务sbatchqsubbsub
查看任务squeueqstatbjobs
删除任务scancelqdelbkill
作业脚本头#SBATCH#PBS#BSUB

所以你不需要把它们看成三套完全不同的东西。先用 Slurm 建立直觉,再遇到 PBS 或 LSF 时,只要把“提交、查看、删除、日志”这几个动作对应过去就行。

3.6 不要在登录节点跑吃资源的任务

登录节点通常是很多人一起使用的入口。如果大家都直接在登录节点上跑长时间大任务,机器很快就会卡住,别人连登录、传文件、查结果都可能受影响。

所以一般规则是:

  • 改文件、传文件、查目录、看日志:可以在登录节点做
  • 编译小程序、测试很短的命令:通常可以在登录节点做,但要克制
  • 正式计算、大规模并行任务、长时间程序:通过调度系统提交