• 进程组

进程组是一组进程的集合,每个进程都属于一个进程组,每个进程组有一个进程组leader进程,进程组的ID(PGID)等于leader进程的ID。对大部分进程来说,它自己就是进程组的leader,并且进程组里面就只有它自己一个进程。

可以通过将信号发送给一个进程组,使进程组中的所有进程都收到该信号。

查看进程的细节

PID为进程自身的ID,PGID为进程所在的进程组的ID, PPID为进程的父进程ID。从上面的结果,我们可以知道ps和cat都是bash的子进程。

  • session(也称为会话)

一个或多个进程组可以构成一个会话 (session)。

一个会话中有一个领导进程(session leader)。会话领导进程的PID是会话的SID(session ID)。会话中的每个进程组称为一个工作(job)。会话可以有一个进程组成为会话的前台工作(foreground),而其他的进程组是后台工作(background)。每个会话可以连接一个控制终端(也可以不连接)。

会话的意义在于将多个工作囊括在一个终端,并取其中的一个工作作为前台,来直接接收该终端的输入输出以及终端信号。 其他工作在后台运行。当我们打开多个终端窗口时,实际上就创建了多个终端会话。每个会话都会有自己的前台工作和后台工作。工作组和会话机制在Linux的许多地方应用。

eg.

当用xshell连接到主机时,即创建了一个session。shell即是session的leader进程,随后shell里面运行的进程都将属于这个session,当shell退出后,该会话中的进程将退出。

shell里面启动一个进程后,一般都会将该进程放到一个单独的进程组,然后该进程fork的所有进程都会属于该进程组,比如多进程的程序,它的所有进程都会属于同一个进程组,当在shell里面按下CTRL+C时,该程序的所有进程都会收到SIGINT而退出。

  • 前台任务

前台任务是独占命令行窗口的任务,只有运行完了或者手动中止该任务,才能执行其他命令。shell中启动一个进程时,默认情况下,该进程是一个前台进程组的leader,可以收到用户的输入,并且可以将输出打印到终端,只有当该进程组退出后,shell才可以再响应用户的输入。

  • 后台任务

与前台任务相对应,后台任务在运行的时候,并不需要与用户交互,它们通常在不打扰用户其它工作的时候默默地执行。使shell可以继续响应用户的输入
后台任务继承当前会话的标准输出(stdout)和标准错误(stderr)。因此,后台任务的所有输出依然会同步地在命令行下显示。
不再继承当前session的标准输入(stdin),你无法向这个任务输入指令了。如果它试图读取标准输入,就会暂停执行(halt)。

可以看出,”后台任务”与”前台任务”的本质区别只有一个:是否继承标准输入。

前台任务变后台任务

  • 启动时变为后台任务 
    只要在命令的后面加上 & ,启动的进程就会成为“后台进程”。但是后台程序的输出仍然会打印到终端,影响用户输入。可以通过yourcommand>log.out  &,将输出重定向到文件中。
  • 将正在运行的“前台任务”变为后台任务 
    先 ctrl+z ,之后执行 bg 命令。相当于让最近一个暂停的“后台任务”继续执行。

CTRL+Z 和 CTRL+C的对比 
  CTRL+Z 和 CTRL+C 都是中断命令,但是他们的作用却不一样. CTRL+C 是强制中断程序的执行,而 CTRL+Z 的是将任务中断,但是此任务并没有结束,仍然在进程中,只是维持挂起的状态,用户可以使用 fg/bg 操作继续前台或后台的任务。

对于后台运行的进程组,在shell里面体现为job的概念,即一个后台进程组就是一个job,可以通过jobs命令查看后台运行的进程组。也可以通过fg命令将后台进程组切换到前端,这样就可以继续接收用户的输入了。如下

  • 守护进程

守护进程(daemon)是指在UNIX或其他多任务操作系统中在 后台执行 的电脑程序, 并不会接受电脑用户的直接操控 。 如果一个进程永远都是以后台方式启动,并且不能受到Shell退出影响而退出,一个正统的做法是将其创建为守护进程(daemon)。守护进程值得是系统长期运行的后台进程,类似Windows服务。守护进程信息通过ps –a无法查看到,需要用到–x参数,当使用这条命令的时候,往往还附上-j参数以查看作业控制信息,其中TPGID一栏为-1就是守护进程

守护进程与后台进程

后台进程的文件描述符是继承于父进程,例如shell,所以它也可以在当前终端下显示输出数据。但是daemon进程自己变成了进程组长,其文件描述符号和控制终端没有关联,是控制台无关的。

基本上任何一个程序都可以后台运行,但守护进程是具有特殊要求的程序,比如要脱离自己的父进程,成为自己的会话组长等,这些要在代码中显式地写出来换句话说,守护进程肯定是后台进程,但反之不成立。

用户退出session之后,后台任务是否会继续执行是判定是否为“守护进程”的依据 
  session退出后,linux系统设计如下:

session就是我们平常所说的终端窗口

  1. 用户准备退出 session
  2. 系统向该 session 发出SIGHUP信号
  3. session 将SIGHUP信号发给所有子进程
  4. 子进程收到SIGHUP信号后,自动退出

前台任务会随着session的退出而退出是因为它收到了SIGHUP信号。
后台任务是否会受到SIGNUP信号,取决于shell的  huponexit  参数。可以通过  $ shopt | grep huponexit  查看该参数的值。

大多数Linux系统,这个参数默认关闭(off)。因此,session退出的时候(exit??还是直接关闭。待验证),不会把SIGHUP信号发给”后台任务”,即此时的后台任务是守护进程,但这显然不够安全。

更安全地创建守护进程: disown 命令 
  通过”后台任务”启动”守护进程”并不保险,因为有的系统的huponexit参数可能是打开的(on)状态。 更保险的方法是使用disown命令。disown命令可以将指定任务从”后台任务”列表(jobs命令的返回结果)之中移除。一个”后台任务”只要不在这个列表之中,session 就肯定不会向它发出SIGHUP信号。

$ node server.js &
$ disown

  执行上面的命令以后,server.js进程就被移出了”后台任务”列表。你可以执行jobs命令验证,输出结果里面,不会有这个进程。 
  但是,这样还存在问题。因为”后台任务”的标准 I/O 继承自当前 session,disown命令并没有改变这一点。一旦”后台任务”读写标准 I/O,就会发现它已经不存在了,所以就报错终止执行。 
  为了解决这个问题,需要对”后台任务”的标准 I/O 进行重定向。

$ node server.js > stdout.txt 2> stderr.txt < /dev/null &
$ disown

  上面这样执行,基本上就没有问题了。

更简便地创建守护进程: nohup 命令 
还有比disown更方便的命令,就是 nohup

$ nohup node server.js &

nohup命令对server.js进程做了三件事。
1.阻止SIGHUP信号发到这个进程。 
2.将stdin重定向到/dev/null,于是该进程不再能够接收任何输入,即使运行在前台。 
3.重定向标准输出和标准错误到文件nohup.out(有时在文件中看不到输出,有可能是程序没有调用flush)。
4.调用exec启动指定的命令(nohup进程将会被新进程取代,但进程ID不变)

从上面nohup干的事可以看出,通过nohup启动的程序有这些特点:

  1. nohup程序不负责将进程放到后台,这也是为什么我们经常在nohup命令后面要加上符号“&”的原因
  2. 由于stdin、stdout和stderr都被重定向了,nohup启动的程序不会读写tty
  3. nohup启动的进程本质上还是属于当前session的一个进程组,所以在当前shell里面可以通过jobs看到nohup启动的程序
  4. 当session leader退出后,该进程会收到SIGHUP信号,但由于nohup帮我们忽略了该信号,所以该进程不会退出
  5. 由于session leader已经退出,而nohup启动的进程属于该session,于是出现了一种情况,那就是通过nohup启动的这个进程组所在的session没有leader,这是一种特殊的情况,内核会帮我们处理这种特殊情况,这里就不再深入介绍

shell中session的退出

当session 中leader进程退出,将导致它所连接终端被hangup,这就意味着该会话结束。但是对于会话的结束,并不会意味着该会话的所以进程都结束。对于daemon进程,在会话中创建,但是不依赖于会话,是常驻在后台的进程。

具体来说当终端hangup时候,内核对会话的leader进程发送SIGHUP信号,它收到SIGHUP信号后并不是马上退出,而是向它的子进程都各自发送一个SIGHUP,将他们都杀死后,自己才退出,但是如果当该leader进程主动退出,而导致的终端hangup那么就不会发送SIGHUP信号给子进程了。

如果又想要某个进程称为常驻后台进程,不随session退出而退出,有下面几个方法:
1. 避免shell发送SIGHUP信号: a. 主动调用exit,而不是直接断开终端;b. 两次fork,因为shell只给子进程发送SIGHUP信号,不给孙进程发送。
2. 忽略SIGHUP信号:进程捕捉到该信号将该信号忽略就行了。

3. 通过setsid()系统调用,那么该调用进程将会退出该session而建立一个新的session。

  • stdin、stdout和stderr

/dev/null 表示空设备文件

stdin标准输入,文件标志符0

stdout标准输出,文件标志符1

stderr标准错误输出,文件标志符2

总的来说,stdin,stdout和stderr还是和终端有密切关系,通常在生产环境时,会将这3个流重定向到其它文件。比如编写守护进程的时候,因为守护进程和终端无关,所以往往会将stdin,stdout和stderr重定向到/dev/null去

  • 2>&1解析
  1. 从command>/dev/null说起

其实这条命令是一个缩写版,对于一个重定向命令,肯定是a > b这种形式,command > /dev/null相当于执行了command 1 > /dev/null。执行command产生了标准输出stdout(用1表示),重定向到/dev/null的设备文件中。

2. command>a 2>a 与 command>a 2>&1的区别

command>a 2>a,等价于command 1>a 2>a;command>a 2>&1,等价于command 1>a 2>&1。

两者都可以理解为执行command产生的标准输入重定向到文件a中,标准错误也重定向到文件a中。但两者的区别在于command>a 2>&1只打开一次文件a,command>a 2>a会打开文件两次,并导致stdout被stderr覆盖。&1的含义就可以理解为用标准输出的引用,引用的就是重定向标准输出产生打开的a。从IO效率上来讲,command 1>a 2>&1比command 1>a 2>a的效率更高。

ctrl+c会发出SIGINT信号,该信号是程序终止(interrupt)信号,用于通知前台进程组终止进程。

终端关闭时,SIGHUP被发送给session首进程,进行响应进程的关闭。

  • ctrl-c, ctrl-z, ctrl-d

ctrl-c: ( kill foreground process ) 发送 SIGINT 信号给前台进程组中的所有进程,强制终止程序的执行;
ctrl-z: ( suspend foreground process ) 发送 SIGTSTP 信号给前台进程组中的所有进程,常用于挂起一个进程,而并非结束进程,用户可以使用使用fg/bg操作恢复执行前台或后台的进程。fg命令在前台恢复执行被挂起的进程,此时可以使用ctrl-z再次挂起该进程,bg命令在后台恢复执行被挂起的进程,而此时将无法使用ctrl-z再次挂起该进程;
 一个比较常用的功能:
    正在使用vi编辑一个文件时,需要执行shell命令查询一些需要的信息,可以使用ctrl-z挂起vi,等执行完shell命令后再使用fg恢复vi继续编辑你的文件(当然,也可以在vi中使用!command方式执行shell命令,但是没有该方法方便)。

ctrl-d: ( Terminate input, or exit shell ) 一个特殊的二进制值,表示 EOF,作用相当于在终端中输入exit后回车;

还有以下几个:
ctrl-/    发送 SIGQUIT 信号给前台进程组中的所有进程,终止前台进程并生成 core 文件
ctrl-s   中断控制台输出
ctrl-q   恢复控制台输出
ctrl-l    清屏

转自:

https://segmentfault.com/a/1190000009152815

https://blog.csdn.net/yanglovefeng/article/details/7872251

https://blog.csdn.net/hust_sheng/article/details/50766752

https://blog.csdn.net/mylizh/article/details/38385739

进程组、session、前台任务、后台任务、守护进程相关推荐

  1. linux进程--进程组、会话、守护进程(八)

    进程组 一个或多个进程的集合 进程组ID: 正整数 两个函数 getpgid(0)=getpgrp() 例子:显示子进程与父进程的进程组id #include <stdio.h> #inc ...

  2. 2进程之间的关系:进程组,会话,守护进程

     1进程组 一个或多个进程的集合,进程组ID是一个正整数.用来获得当前进程组ID的函数. pid_t getpgid(pid_t pid) pid_t getpgrp(void) 获得父子进程进程 ...

  3. linux系统编程之进程(八):守护进程详解及创建,daemon()使用

    linux系统编程之进程(八):守护进程详解及创建,daemon()使用 一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等 ...

  4. Linux:守护进程解析、如何实现守护进程

    1.守护进程: 守护进程也称精灵进程(Daemon),是运行在后台的⼀一种特殊进程.它独立于控制终端且周期性地执行某种任务或等待处理某些发生的事件.守护进程是⼀一种很有用的进程.Linux的大多数服务 ...

  5. Linux内核进程,线程,进程组,会话组织模型以及进程管理

    Linux 内核创世与创生 Linux宇宙诞生之时,创建了三个重要进程,三个进程的PID分别为0,1,2. 做一个不太恰当的比喻,你可以现象成组件一个创业团队,第一步需要找到CEO,CTO,CFO,有 ...

  6. php守护进程热更新,服务器编程--守护进程

    守护(Daemon)进程又叫作"精灵进程",虽然守护进程这个名字更为常用,但是个人感觉还是精灵进程较为机灵可爱些.服务器进程一般都是守护进程,这类进程的一个显著特点就是无交互地在后 ...

  7. linux apache守护进程,Linux基础命令---httpd守护进程

    httpd httpd是apache超文本传输协议的主程序,它被设计成一个独立运行的守护进程.httpd会建立一个线程池来处理http请求. 此命令的适用范围:RedHat.RHEL.Ubuntu.C ...

  8. linux启动守护进程失败,Ubuntu Linux设置守护进程时出错的解决

    Ubuntu系统使用源从7.10升级到8.04后,启动并在用户登录后,界面无响应5分钟左右后,弹出出错信息: 启动GNOME设置守护进程时出错 主题.声音或者背景设置等可能不会正常工作. 最后的错误信 ...

  9. python 守护程序检测进程是否存在_python创建守护进程的疑问

    我自己写了一个简易的下载和文件执行的客户端,如下 """ 省略若干代码 """ #执行下载函数 def do_script(): " ...

  10. android无法启动守护进程,Android Studio无法启动守护进程异常怎么解决?

    大家好,我的这篇文章来自于我个人做的小项目是关于教你如何能过三关,斩五将的通过驾考,那么废话不多说下面是本人总结的错误集,本来仅供自己不要忘记,但如果觉得本人处理不好或没效果还是能够帮我提提意见,因为 ...

最新文章

  1. python twisted教程_Python Twisted系列教程16:Twisted 进程守护
  2. 【我的区块链之路】- Hyperledger fabric的简单入门(四)链码的编写及调试
  3. ValidateUtil
  4. ORA-00119: invalid specification for system parameter LOCAL_LISTENER;
  5. C#语法基础(三)----窗体设计
  6. php webservice 上传大文件,JS和WebService大文件上传代码分享
  7. grafana 批量添加图表
  8. 希尔伯特变换分析及应用
  9. 数据治理——主数据项目实施
  10. autojs版本的QQ聊天自动回复机器人源码免费分享,不需要root权限
  11. python直角三角形的两个直角边、求斜边_直角三角形斜边公式计算器 两个直角边边长的平方加起来等...
  12. poj_3987 Trie图
  13. 用了 DDD 以后,代码更难懂了?看完这篇你就明白了
  14. 后缀是lnk是什么文件_ink是什么文件?ink文件怎么打开
  15. 计算机储存容量单位的进率,进制、存储与容量
  16. iVMS-4200 Vs区别_【欧国联:德国 VS 瑞士】体育足球赛事专业紅單推荐
  17. chrome安装插件提示image decode failed
  18. html5用css加粗字体,在CSS里怎样设置字体的浑厚,这个浑厚不是加粗……
  19. java注释【单行注释,多行注释,文档注释】
  20. Linux进程与线程

热门文章

  1. php扩展dio,php_dio.dll下载|
  2. 伯克利数学博士资格一考题
  3. matlab ema 向量化,Matlab匿名函数,向量化和预分配,函数的函数,P码文件
  4. 雨课堂中的课件如何下载
  5. 如何让孩子戒掉手机瘾游戏瘾,小学生迷恋游戏怎么办?
  6. 建立完善的员工晋升机制_建立合理的晋升机制,给员工发展的空间
  7. pygame壁球游戏之节奏型操控型
  8. UnityShader Reversed-Z的理解
  9. Android 13 功能和变更列表
  10. AJAX与JSON数据交互处理