用以促学——Linux进程后台运行的原理、方法、比较及其实现

用以促学——Linux进程后台运行的原理、方法、比较及其实现

前言

相关基础知识

  • 操作系统:进程相关概念,调度等
  • Linux

应用场景

后台运行不用说了吧,有时候在服务器上面跑个爬虫啥的,都要用的。

一般远程连接服务器的时候,有时候网络不好或者不想一直开着终端的话,后台运行就很有必要了。

问题所在

一般我们连接服务器,都是通过SSH(Secure Shell)进行连接,本文也着重介绍这种情况。

当我们通过ssh运行一些耗时的任务后,经常会由于网络不稳定、或者电脑关机休眠之类的导致任务中途失败。

如何让命令开始执行后优雅的退出本地终端、关闭ssh并且不会影响其运行呢?

在开始之前,我们需要了解一些概念,当然,你也可以选择跳过它。

linux概念说明

session(会话)

定义

会话是一组进程的集合(并不是进程)

集合内的每个进程的sid(SessionID)是相同的,代表他们属于同一个集合

会话的创建

会话是由会话中的第一个进程创建的 (领头进程session leader)pid(ProcessID) 等于 sid

这里简单介绍一个函数 setsid

子进程默认从父进程继承了:SessionID、进程组ID和打开的终端。
子进程如果要脱离这些,可通过setsid来实现。
setsid帮助一个进程脱离从父进程继承而来的已打开的终端、隶属进程组和隶属的会话。

setsid很好理解嘛,就是长大了翅膀硬了飞了,脱离父进程。

一个进程当它setsid后,一个新session就被建立了,并且他就是那个session leader

会话中的进程是树状结构。一个session中的进程,一定是session leader或者其子孙进程

就像自立门户一样。

会话的消亡
  • session中的所有进程都结束时消亡

  • session leader退出(或者结束)时,session中的进程会收到SIGHUP信号,默认结束掉进程。

    如果该进程对SIGHUP做了处理,不结束,那么会受到SIGCONT信号,让进程正常执行完毕

signal(信号)

SIGHUP (signal hang up)

意为:信号挂起

是一个进程的 **控制终端 **在关闭时,发送给进程的信号。

SIGINT (Signal interrupt)

意为:信号中断

当用户希望中断进程时**(关联Ctrl+C)**,SIGINT信号由其控制终端发送到进程。

与SIGTERM相比,其只能结束前台进程

SIGTERM (Signal terminate)

意为:信号中止

Sigterm信号被发送到一个进程以请求其终止。

这允许该进程友好的终止、释放资源,并在适当的情况下保存状态。

在某种程度上sigint与sigterm几乎相同

与Sigkill信号不同,它可以被阻塞、处理和忽略。

kill 命令默认不带参数时,发送的信号就是SIGTERM,让程序友好的退出。

kill -9 发送的即是SIGKILL,强制杀死,无条件终止。

SIGKILL (Signal kill)

意为:信号杀死

SIGKILL信号被发送到进程以使其立即终止。强制性的

与SIGTERM和SIGINT相反,这个信号不能被捕获或忽略,接收进程在接收到这个信号后不能进行任何清理。

有一些例外在这里不做赘述。

SIGCONT (Signal continue)

意为:信号继续

SIGCONT信号指示操作系统继续(重新启动)先前由SIGSTOP或SIGTSTP信号暂停的进程。

这个信号的一个重要用途是在Unix shell中的作业控制中。

后台运行进程的方法

有些时候,当你开始一个耗时的任务,你的终端会被占用,你无法输入你想输入的下一条指令。

这很好解决,用符号&即可。我们一般将它附在命令后面可以使进程在后台执行,不会占用前台界面。

但它实际上是在当前会话中开启了一个后台作业。

但此时终端被关闭后,进程还是会退出。这是因为,& 符号只有让进程让出前台终端的功能,无法让进程不受 SIGHUP 信号的影响。

这显然不是我们想要的

如果我们想要让进程脱离终端去运行呢?,接下来我们进行讨论

当通过终端运行命令时,发生了什么?

通常,用户登陆终端时,会创建一个 session ,session 中的领头进程是运行用户登录 shell 的进程。

在这之后,用户新创建的每个进程都会在这个session里。

当终端关闭时,又发生了什么?

当用户注销或者网络断开时,SIGHUP 信号会被发送到会话中的所有子进程。

SIGHUP 的默认处理方式是终止收到该信号的进程。所以若程序中没有捕捉该信号,当终端关闭后,会话中获得进程就会退出。

由此可以想到,我们的解决办法有两种方法:

  1. 让进程忽略 SIGHUP 信号。
  2. 让进程运行在新的会话里从而成为不属于此终端的子进程。

后台运行的实现

使用nohup指令

顾名思义,nohup指令使进程不受 SIGHUP 信号的影响。即第一种方法

nohup py run.py

当执行上述命令后,进程还会一直占用着终端前台。但当终端被关闭或连接断开,进程还是会继运行。

默认会将输出存至当前文件夹下的 nohup.out 文件(不存在则创建)。

如果同时搭配 & 就可以实现让出前台的同时,使得进程不受终端关闭的影响

使用setsid指令

在前面有简单介绍这个指令。它的作用是让进程转移到一个新的会话运行。即第二种方法

setsid py run.py

它直接创建了一个新的会话来运行,那么原会话的终端的状态就再也不会影响到此进程了。

我们使用pstree -a |grep -C 6 ping来查看一下发生的变化

默认

  |-sshd
  |   `-sshd 
  |       `-sshd  
  |           `-bash
  |               |-grep -C 6 ping
  |               |-ping 106.55.250.70	<<-在这里
  |               `-pstree -a

使用 setsid

  |-ping 106.55.250.70	<<-在这里
  |-sshd
  |   `-sshd 
  |       `-sshd  
  |           `-bash
  |               |-grep -C 6 ping
  |               `-pstree -a

使用了 setsid 后,ping已与 sshd 同级,即属于 init 进程的子进程了。

但是 setsid 并没有为进程分配一个输出终端,所以进程还是会输出到当前终端上。

比较

nohup&setsidscreendisown -h
用途不挂断地运行命令让出前台创建一个新的会话并运行进程伪终端移出作业列表
原理使进程不受 SIGHUP 信号的影响当前会话中开启了一个后台作业
又称守护进程
脱离父进程,开启新会话直接开一个虚拟终端将作业进程转为init的子进程
进程位置当前会话当前会话新的会话对应伪终端会话当前会话,关闭后到init
启动nohup py run.pypy run.py &setsid py run.pyscreen创建bg %1 && disown %1
正在运行当前终端即是jobs查看后台正在运行(仅当前终端可用)ps对应伪终端即是ps
如何停止Ctrl+C使用fg将后台切换到前台后Ctrl+Ckill切换到伪终端内进行操作kill
前台终端不让出让出不让出不让出对应伪终端与&相同
输出输出重定向,默认到当前目录下 nohup.out 文件使用标准输出时(echo、ls)仍会一直占用前台(例如ping指令)当前终端对应伪终端与&相同
关闭sshSIGHUP 信号,程序免疫SIGHUP 信号,程序关闭不受影响不受影响转换为init的子进程
Ctrl+CSIGINT 信号,程序关闭不受影响不受影响在对应伪终端内有效与&相同
配合&使用时

查看:jobs
停止:fg+Ctrl+C
Ctrl+C 不能关闭程序。
Ctrl+C + jobs 可以关闭。

其他

huponexit

一般默认为off,仅针对使用exit命令退出终端的情况,这时不会发送sighup信号。

参考资料

Linux中的session的概念

Linux session(会话)

Signal (IPC)

Linux - 请允许我静静地后台运行

Linux 中的 &

Linux让进程后台运行且连接断开不影响(nohup、setsid、disown、screen)

Linux后台进程管理以及ctrl+z(挂起)、ctrl+c(中断)、ctrl+\(退出)和ctrl+d(EOF)的区别

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值