任务后台运行

更新时间:

参考本节后台运行任务,避免关闭网页/终端时将相应任务也停止了。

# 背景说明

使用平台提供的网页终端,会遇到 关闭终端则任务停止 的问题。其实这不是平台的问题,而是业界终端工具都有此问题。

说明:平台的网页终端,在关闭网页时,终端也会随之关闭,从而停止任务。

为何任务会随终端关闭而停止?
用户与计算机的临时的交互,称为一次"会话"(session)。在 Linux 下,一个 session 是由一组进程组构成的,每个进程组又由多个进程构成。在一个 Bash 上运行的程序都归属于一个 session,每个“会话”又可以关联一个控制终端(Controlling Terminal)。终端窗口与其中启动的进程是连在一起的,打开窗口,会话开始;关闭窗口,会话结束,会话内部的进程也会随之终止,不管有没有运行完。

典型示例:SSH 登录远程计算机,打开一个远程窗口执行命令。这时,网络突然断线,再次登录的时候,是找不回上一次执行的命令的。因为上一次 SSH 会话已经终止了,里面的进程也随之消失了。

# 如何后台运行

如下方法可以后台运行任务,不受终端关闭的影响:

  • 方①:使用 Linux 的 tmux/screen 工具,在终端内使用这些工具开启任务后台运行。
  • 方②:以 nohup 方式起任务,即在启动命令前后加上 nohup 和 &,例如 nohup start.sh -u gemini &
  • 方③:使用 JupyterLab 自带终端运行任务,关闭网页并不会关闭 JupyterLab。(JupyterLab 可同时开启多个终端)

说明:训练尽可能使用平台的离线训练功能,训练完成会自动结束。

# tmux

tmux 是一个优秀的终端复用软件,通过一个终端登录远程主机并运行 tmux 后,在其中可以开启多个控制台而无需再 “浪费” 多余的终端来连接这台远程主机。

# 安装

官方镜像已预置该工具,如仍有安装需求,可参考如下说明。

Ubuntu

sudo apt update
sudo apt-get -y install tmux

CentOS

sudo yum install tmux

# 常见使用

新建会话

tmux               # 新建一个无名称的会话
tmux new -s <session-name>   # 新建有名称的会话,<session-name> 为会话名称。

进入/退出会话

tmux a        # 默认进入第一个会话,是 `tmux attach-session` 的简写形式
tmux a -t <session-name>   # 进入到名称为 <session-name> 的会话,是 `tmux attach -t <session-name>` 的简写形式
tmux detach    # 断开当前会话,会话在后台运行

查看会话

tmux ls    # 查看所有会话,是 `tmux list-session` 的简写形式,提倡使用简写形式

关闭会话

tmux kill-session -t <session-name>   # 关闭名为 <session-name> 的会话

# 会话内快捷操作

使用快捷键,需先输入 Ctrl+b 激活控制台后,再输入如下快捷指令,这样控制台才能识别出这是快捷指令。

说明:下表仅列出您可能常用的快捷指令。

快捷指令 说明
d 断开当前会话,并让会话后台。
s 显示会话列表用于选择并切换。

# 使用示例

场景:在开发环境提交了一个简单训练,训练过程需要 10 分钟,此时您想查看下上次的训练结果。

解决方案:使用 tmux 新建两个会话,一个用于训练,一个用于推理。详情可参考下图和步骤解析。

  1. 新建 train01 会话用于训练。

    tmux new -s train01
    
  2. 在 train01 中提交训练任务。

  3. 退出 train01(先按 crtl+b ,松手后再按 d)。

  4. 再创建 deduction 会话用于推理。

    tmux new -s deduction
    
  5. 在 deduction 中执行推理。 推理过程较久,如需切换到 train01 看看训练情况,可以:

    1. 先按 crtl+b ,松手后再按 d,弹出会话列表。
    2. 按 ↑ 或 ↓ 键,切换所选会话为 train01,然后按 Enter 进入 train01。

# Screen

Screen 是一款用于命令行终端切换的自由软件。用户可以通过该软件同时连接多个本地或远程的命令行会话,并在其间自由切换。Screen 可以看作是窗口管理器的命令行界面版本。它提供了统一的管理多个会话的界面和相应的功能。

# 安装

官方镜像已预置该工具,如仍有安装需求,可参考如下说明。
ubuntu

sudo apt update
sudo apt-get install screen

# 常见使用

新建会话

screen      # 新建一个无名称的会话
screen -S <session_name>           # 新建一个叫 <session_name> 的会话

进入/退出会话

screen -r <session_name>            # 回到 <session_name> 这个 session
screen -d <session_name>            # 远程 detach 某个 session
#在session内按 ctrl+a+d 组合键     # 退出 session 并后台执行任务

查看会话

screen -ls    # 列出当前所有的 session,是 screen -list 的简写形式

关闭会话

screen -d -r <session_name>        # 结束当前 session 并回到 session_name 这个 session

# 使用示例

  1. 创建一个 test 会话。

    screen -S test
    

    此时会新建一个窗口,仿佛什么也没有发生似的,其实你已经进入 Screen 的世界。

  2. 在 test 会话中执行一段命令。

    dd if=/dev/zero of=/data/1 count=500M bs=10M
    

    光标一直闪烁,表示任务正在执行。

  3. ctrl+a+d 组合键,退出 test 会话,并使其后台运行。
    退出后,提示从 test 会话退出。 detach

  4. 执行 top 命令,查看刚才 test 会话中执行的命令是否在后台执行。
    此时我们用 top 命令可以看到,有一个 dd 命令在执行,并且负载越来越高。只要不终止 screen 的进程,任务就会一直在后台执行。此时我们就可以做其他想做的事,而不必一直等着任务执行完成。也不必担心任务被中断,即使使用了 logout 命令。

  5. 执行 screen ls 查看会话,返回如下信息。

    其中 8798 是进程的 pid,test 是会话的名称。

  6. 执行如下命令重新进入 test 会话,查看任务执行情况。

    screen -r test
    

    进入 screen,重新连接会话,将任务调取至前台,若还是光标闪烁,表示任务未执行完成。
    但出现如下结果,表示任务已经执行完成。但是有终端在连接会话。

    [root@ljc ~]# screen -r 8798
    There is a screen on:8798.test       (Attached)
    There is no screen to be resumed matching 8798.
    

    说明:attached 表示有终端在连接会话。

  7. 执行 exit,退出并关闭会话。

# 完整命令参考

screen [-AmRvx -ls -wipe][-d <作业名称>][-h <行数>][-r <作业名称>][-s ][-S <作业名称>]

参数 说明
-A 将所有的视窗都调整为目前终端机的大小。
-d <作业名称> 将指定的 screen 作业离线。
-h <行数> 指定视窗的缓冲区行数。
-m 即使目前已在作业中的 screen 作业,仍强制建立新的 screen 作业。
-r <作业名称> 恢复离线的 screen 作业。
-R 先试图恢复离线的作业。若找不到离线的作业,即建立新的 screen 作业。
-s 指定建立新视窗时,所要执行的 shell。
-S <作业名称> 指定 screen 作业的名称。
-v 显示版本信息。
-x 恢复之前离线的 screen 作业。
-ls或–list 显示目前所有的 screen 作业。
-wipe 检查目前所有的 screen 作业,并删除已经无法使用的 screen 作业。

# nohup

nohup 英文全称 no hang up(不挂起),用于在系统后台不挂断地运行命令,退出终端不会影响程序的运行。

# 语法格式

nohup Command [ Arg … ] [ & ]

  • Command:要执行的命令。

  • Arg:一些参数,可以指定输出文件,无特殊要求可不使用。

  • &:让命令在后台执行,终端退出后命令仍旧执行。

# 使用示例

在后台执行 root 目录下的 runoob.sh 脚本。

nohup /root/runoob.sh &

返回如下信息,则后台运行成功。

appending output to nohup.out