用以促学——Linux进程后台运行的原理、方法、比较及其实现
用以促学——Linux进程后台运行的原理、方法、比较及其实现
文章目录
- 用以促学——Linux进程后台运行的原理、方法、比较及其实现
- 前言
- 相关基础知识
- 应用场景
- 问题所在
- linux概念说明
- session(会话)
- 定义
- 会话的创建
- 会话的消亡
- signal(信号)
- SIGHUP (*signal hang up*)
- SIGINT (*Signal interrupt*)
- SIGTERM (*Signal terminate*)
- SIGKILL (*Signal kill*)
- SIGCONT (*Signal continue*)
- 后台运行进程的方法
- 当通过终端运行命令时,发生了什么?
- 当终端关闭时,又发生了什么?
- 由此可以想到,我们的解决办法有两种方法:
- 后台运行的实现
- 使用nohup指令
- 使用setsid指令
- 比较
- 其他
- huponexit
- 参考资料
前言
相关基础知识
- 操作系统:进程相关概念,调度等
- 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
的默认处理方式是终止收到该信号的进程。所以若程序中没有捕捉该信号,当终端关闭后,会话中获得进程就会退出。
由此可以想到,我们的解决办法有两种方法:
- 让进程忽略
SIGHUP
信号。 - 让进程运行在新的会话里从而成为不属于此终端的子进程。
后台运行的实现
使用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 | & | setsid | screen | disown -h | |
---|---|---|---|---|---|
用途 | 不挂断地运行命令 | 让出前台 | 创建一个新的会话并运行进程 | 伪终端 | 移出作业列表 |
原理 | 使进程不受 SIGHUP 信号的影响 |
在当前会话中开启了一个后台作业 又称守护进程 |
脱离父进程,开启新会话 | 直接开一个虚拟终端 | 将作业进程转为init的子进程 |
进程位置 | 当前会话 | 当前会话 | 新的会话 | 对应伪终端会话 | 当前会话,关闭后到init |
启动 | nohup py run.py | py run.py & | setsid py run.py | screen创建 | bg %1 && disown %1 |
正在运行 | 当前终端即是 | jobs查看后台正在运行(仅当前终端可用) | ps | 对应伪终端即是 | ps |
如何停止 | Ctrl+C | 使用fg将后台切换到前台后Ctrl+C | kill | 切换到伪终端内进行操作 | kill |
前台终端 | 不让出 | 让出 | 不让出 | 不让出对应伪终端 | 与&相同 |
输出 |
输出重定向,默认到当前目录下 nohup.out 文件
|
使用标准输出时(echo、ls)仍会一直占用前台(例如ping指令) | 当前终端 | 对应伪终端 | 与&相同 |
关闭ssh |
SIGHUP 信号,程序免疫
|
SIGHUP 信号,程序关闭
|
不受影响 | 不受影响 | 转换为init的子进程 |
Ctrl+C |
SIGINT 信号,程序关闭
|
不受影响 | 不受影响 | 在对应伪终端内有效 | 与&相同 |
配合&使用时
查看: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)的区别
用以促学——Linux进程后台运行的原理、方法、比较及其实现相关推荐
- Linux 进程后台运行
Linux 进程后台运行 1.进程在当前终端后台运行.(关闭终端后进程自动退出) sh test.sh &注:运行进程后跟 "&" 2.进程长期后台运行不受终端关闭 ...
- 转-Linux进程后台运行的几种方法
为什么80%的码农都做不了架构师?>>> http://linux.ctocio.com.cn/179/12162679.shtml 我们经常会碰到这样的问题,用telnet/ ...
- linux进程suspended状态,linux进程后台运行
在linux上启动Web服务,当退出终端后,Web服务进程也会随着关闭.产生这种问题的原因在于,当用户注销或者网络断开后,终端后收到挂断信号(SIGHUP),并向子进程广播SIGHUP信号,子进程收到 ...
- linux进程后台运行的几种方法 - nohup/setsid//disown/screen
我们经常会碰到这样的问题,用 telnet/ssh 登录了远程的 Linux 服务器,运行了一些耗时较长的任务, 结果却由于网络的不稳定导致任务中途失败.如何让命令提交后不受本地关闭终端窗口/网络断开 ...
- Linux 进程后台运行的几种方式 screen
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/80580779 本文出自[赵彦军的博客] screen是Linux窗口管理器,用户可 ...
- 【Linux系统理论操作学习26】LInux的后台运行,重定向输出,前后台进程转换和管理
1 输出的后台运行 1.1 简单后台运行 nohup表示程序不被挂起 &表示后台运行程序 如果说使用&,就会出现问题:后台执行的进程,其父进程还是当前终端shell的进程,而一旦父进程 ...
- Linux 下后台运行程序,查看和关闭后台运行程序(转载)
1.运行.sh文件 直接用./sh 文件就可以运行,但是如果想后台运行,即使关闭当前的终端也可以运行的话,需要nohup命令和&命令. (1)&命令 功能:加在一个命令的最后,可以把这 ...
- Linux在后台运行python程序、脚本程序、可执行程序等,关闭终端仍可保持程序运行
欢迎大家关注笔者,你的关注是我持续更博的最大动力 原创文章,转载告知,盗版必究 Linux在后台运行python程序.脚本程序.可执行程序等,关闭终端仍可保持程序运行 文章目录: 1 为什么需要后台运 ...
- 项目如何在Linux系统后台运行以及调回前台运行
第一类:nodejs服务 使用forever 工具管理nodejs服务在后台运行:需要先安装forever工具 sudo npm install forever -g 1.启动(在后台运行) fore ...
最新文章
- PT100热电阻校准模块设计
- 【数据库】MySQL的C语言接口学习
- 干货|一文看懂美国共享出行3大领域8大头部玩家
- laravel多种安装方法
- python鸢尾花数据集聚类_R语言鸢尾花iris数据集的层次聚类分析
- Android中BroadcastReceiver
- javaSE各阶段练习题--数组
- Android应用开发—Intent组件详解
- PERKET(洛谷P2036题题解,Java语言描述)
- 技术支持和研发哪个好_考拉海购技术支持的前世今生,聊聊家常“黑历史”
- 不能错过!简单易懂的哈希表总结
- 用数据分析福尔摩斯探案集,里面有你不曾发现的秘密
- 使用TextToSpeech朗读文字
- 葱油拌面的做法 手残党都能学会
- Luogu P1530 分数化小数 Fractions to Decimals(模拟)
- 瑞利分布(Rayleigh Distribution)回顾
- 原创:编写jquery 选项卡插件
- 龙佰集团拟35亿投建20万吨锂电负极项目 钛白粉龙头转型可期
- [MSF]server/capture/http_javascript_keylogger键盘记录
- 【项目实战】YOLOV5 +实时吸烟目标检测+手把手教学+开源全部