Linux守护进程¶
在Linux中:
- 打开terminal,也就是终端程序,之后可以获得一个shell
- 通过ssh连接到linux的ssh-server 服务器,也可以获得一个shell
通常我们都是通过以上两种方式来获得一个shell,之后运行程序的,此时我需要纠正一个概念,我们通常都说获得一个shell,本质上来说,我们获取了一个session(会话,以下session都是会话)
举例说明


- pid,pgid,sid均为889的 sshd 守护进程生成一个SID为1419的session,同时创建了一个pid为1419的子进程“sshd: yifan [priv]” ,并且创建了一个进程组,此进程就是进程组的leader,进程组的PGID等于此进程的pid 1419,这个进程就是该session的leader
- “sshd: yifan [priv]”创建了一个PID为1578子进程 “sshd: yifan@pts/0,pts/1” ,其实就是开了一个虚拟终端 pts
- 虚拟终端pts生成了一个SID为1588的session,创建了一个pid为1588的子进程 “zsh”,并且创建了一个新的进程组,新进程组的PGID等于新的子进程的PID为1588,这个子进程为进程组的leader,也是这个session的leader。
- zsh创建了一个pid为3663的子进程 “ping baidu.com”,同时创建一个新的进程组,PGID为3663,并且这是一个前台进程

可以发现存在不同
这里是 ps 命令的 STAT 列,具体字符含义如下
- D 不能中断的进程(通常为IO)
- R 正在运行中的进程
- S 已经中断的进程,通常情况下,系统中大部分进程都是这个状态
- T 已经停止或者暂停的进程,如果我们正在运行一个命令,比如说sleep 10,如果我们按一下ctrl -z 让他暂停,那我们用ps查看就会显示T这个状态
- W 这个好像是说,从内核2.6xx 以后,表示为没有足够的内存页分配
- X 已经死掉的进程(这个好像从来不会出现)
- Z 僵尸进程,杀不掉,打不死的垃圾进程,占系统一小点资源,不过没有关系。如果太多,就有问题了。一般不会出现。
下面一些是BSD风格的参数
- < 高优先级进程
- N 低优先级进程
- L 在内存中被锁了内存分页
- s 主进程
- l 多线程进程
- + 代表在前台运行的进程
可以看出
- 执行 pingbaidu.com 的时候ping是前台运行的进程, bash是后台运行的进程
- 执行 ping baidu.com & 的时候ping是后台运行的进程, bash是前台运行的进程
进程组¶
进程的概念大家都能理解的话,进程组就很好说了,其实就是一堆进程捆一起了,之后形成一个组就叫进程组了
这么做肯定是有意义的,不然Linux也不会这么搞,主要还是为了方便管理。
公司为了方便管理,给人分组,方便分配工作;社会为了方便管理,给人区分成年人,未成年人,老人;我们又因为爱好,信念等被分成了各种各样的小组...
系统把同一个job(作业)的进程分成一个组,既然有组织肯定得有组长,组的ID(PGID)就采用组长的PID
这里有一个问题,如果组长进程死亡了,小组还存在吗?如果存在组长归谁?
如果组长进程死亡了,小组只要还剩下进程就会存在,此时组长不会变,PGID也不会变;就像纪念一样...
这里一定要注意,你杀的是一个进程组,一定要注意,进程组里是否有正常业务进程,别杀错了
Session¶
其实文章开头我们已经简单提到过了,我们一般讨论的都是shell session,我们打开一个新的终端就会创建一个session,每个session都是由一个或者多个进程组组成的,每个进程组称为 job,这里job不是任务,而叫作业
从描述中可以看出,session管理的范围要比进程组大,打开一个终端,你执行100条命令,只要没有新的session生成(调用 setsid()函数可以生成新的session ),那么这些命令可以通过session进行统一管理,当然最常见的管理方式还是全部杀死,但是这个杀伤力太大了,所以一般不使用,主要还是了解session的概念,从web安全过来对于session这种机制应该很容易理解。
session中的第一个进程(一般是bash)的PID就是session的SID
现在大招来了,如何干掉整个session呢?
守护进程(daemon)¶
守护进程这个词经常听到,名字还挺温暖,遗憾的是总是在处理linux挖矿病毒的案例中听到,简直破坏美感 守护进程的一个特点就是进程不受任何终端控制
不受任何终端控制这个定义似乎有些模糊,所以我试图去找到一些限定条件,大部分人是这样说的:
- 随系统启动而启动
- 父进程是init,也就是ppid为1
- 在后台运行
- 进程名字通常以字母 d 结束
- ps显示中终端名设置为问号(?),终端前台进程组ID设置为-1
- 工作目录为 (根)
这其中很明显不完全准确,但是也都是基于实际情况分析出来的,所以我一直在纠结后台进程、nohup起的后台进程和守护进程是什么关系,直到遇到了这篇文章,我觉得才是说的比较透彻的
https://www.cnblogs.com/lvyahui/p/7389554.html
我直接摘过来:
- 没有控制终端,终端名设置为?号:也就意味着没有 stdin 0 、stdout 1、stderr 2
- 父进程不是用户创建的进程,init进程或者systemd(pid=1)以及用户人为启动的用户层进程一般以pid=1的进程为父进程,而以kthreadd内核进程创建的守护进程以kthreadd为父进程
- 守护进程一般是会话首进程、组长进程。
- 工作目录为/(根),主要是为了防止占用磁盘导致无法卸载磁盘
参考文章:https://cloud.tencent.com/developer/article/1803425