xshell原理
可能我们都在使用xshell时,都会遇到一些问题,就是你在xshell运行了你的服务器。可是你把xshell页面一关,你的服务器就自动关闭了,这是为什么呢??
本质是因为我们的xshell在登陆服务器时,会创建一个会话,而在这个会话中,只能允许一个进程在前台运行,多个进程在后台运行。而会话退出时会话的内容也会跟着退出,因为会话的内容都是以bash为父进程创建的。我们在命令行输入执行的进程,都是以bash为父进程创建的。
我们还要明白一个进程组的概念,我们可以分别执行 sleep 10000 | sleep 20000 | sleep 30000 &
和 sleep 40000 | sleep 50000 | sleep 60000 &
命令,会建立6个睡眠的进程,而&的意思是在后台中运行。然后我们输入jobs,可以发现有2个进程组。
我们在查看进程,会发现有2个进程组,且进程组id和进程id相同的进程即为进程组组长。
而这个2个进程组组长都是由bash创建的。举个例子:
bash 就是大老板,它给了A一大笔钱,让A自己找几个人帮他完成一些任务。随后A就找了自己的兄弟一起给大老板bash干活。然后bash又找到B,给了B一大笔钱,让B自己组个队伍去帮他完成另一个任务。随后B也拉上了自己的兄弟们一起为大老板bash干活。
这里的大老板就是bash,A就是进程组组长,B是另一个进程组的组长。而它们都是为bash干活,而一旦bash退出,那么它们也自然会跟着退出。因为老板都挂了,进程组们肯定原地解散了。
而我们发现当命令行处于前台状态在运行进程时,就无法在使用命令行了。这本质的原因就是因为一个会话最多只允许一个进程在前台运行。
那么我们怎么让A和B不受会话的限制,即使会话退出了也不会影响它们运行呢?
很简单,我们让进程组组长不要替别人干活啦!自己出去单干,那么自己就是老大!让它们自己出去自成终端!自成进程组!自成会话!除非用户自己关闭或者操作系统挂了,那么它们就不在受到会话的影响。即使会话退出,它们依旧可以运行。这种进程我们把它称为守护进程 ,也可以叫做精灵进程 ,本质上还是一个孤儿进程
需要注意的是,想要自己出去单干,那么自己必须当老大。也就是说自己必须成为进程组的组长。
创建守护进程
上面我说过,守护进程的本质还是个孤儿进程,那么就意味着它必定会被操作系统领养。
实现守护进程我们可以分三个重要步骤,若干个小步骤。
1. 让调用的进程忽略掉异常信号
比如SIGPIPE信号,如果现在我要把服务器自身独立成为会话。那么要忽略掉这个信号,避免客户端搞事(在服务器读取时客户端关闭,服务器会收到SIGPIPE信号)。
2. 自成进程组
有一个setsid函数,可以让自己自成进程组,并自身处于新会话内,也就是说脱离了bash的掌控之中了!但是有个条件!那就是调用的进程本身不能是进程组! ,否则会调用失败!只要fork一下,那么fork出来的子进程就绝对部署进程组组长。这时候再把父进程立马退出,让子进程执行setsid。即可让子进程脱离bash的魔掌!
该函数调用成功返回进程 的pid,调用失败返回-1.
#include <unistd.h>
pid_t setsid(void);
手册对函数的说明:
3 .关闭或重定向进程默认打开的文件
如果我的服务器有大量的输出内容,如果不关闭默认打开的文件的话。那么可能会占用系统的IO资源。而在/dev/null
路径的null文件。是一个“黑洞” ,无论你往里面读还是写。都不会发生什么,可以认为是个垃圾桶,但是在垃圾桶里面还能捡到东西,而你这里面你读不到消息,写进去的消息也没有反应,所以我愿称