守护进程

守护进程(也叫精灵进程):是指那些长时间运行在服务器上的进程,在后台执行,不需要与用户直接交互的进程,在Windows上叫做服务。

守护进程的编程流程:

  • 1,首先fork()产生一个子进程,退出父进程
  • 2,setsid();
  • 3,再fork(),退出父进程[可选]
  • 4,改变当前工作路径;
  • 5,umask 清除掩码;
  • 6,close关闭文件描述符(若有僵尸进程则要处理僵死进程)

为什么是这么个流程呢?将清楚这个流程之前我们先介绍几个概念

会话:每打开一个终端,就和系统建立一个会话(在Linux中一般是指bash)(用getsid(0)可以获得当前会话的id)

会话首进程:在终端运行的第一个进程(通常用会话首进程的PID作为会话id)

进程组:每个进程被创建后都属于一个进程组(用getpgrp()可以获得当前进程组的组id)

组长进程:进程组中PID与组id相等的进程

下图表示这几个进程之间的关系

守护进程

第一步,我们知道,通常如果我们关闭一个终端(会话),那么这个终端上的所有进程就都会销毁,而守护进程的特点是不需要与用户直接交互,也就是与终端是否关闭无关,所以我们一开始就要fork()一个子进程,使父进程退出,保证我们能够创建新会话,创建新会话不允许使用组长进程,所以我们首先fork()并且退出父进程;

第二步接着调用setsid()创建一个新会话;

第三步执行不执行都可以,其目的是使当前进程彻底与当前终端无关;

第四步将其拷贝在不易被卸载的目录下保证其可以一直执行;

第五步是为了赋权限;

第六步需要关闭打开过的所有文件描述符;

代码如下:

守护进程

 其实在关闭文件描述符之后,我们就已经实现了这个守护进程。为了检测我们是否真正实现了一个守护进程,我们在下面定义一个死循环,循环往一个名为/tmp/cy1207.log的文件中写入数据,写入的内容是获取时间字符串,我们可以在一个会话中运行我们写的这个守护进程,然后关闭会话,打开另一个会话,打开我们自己定义的日志文件,看看是否有数据不断被写入,就可以检测我们写的守护进程成不成功啦。

查看结果如下图:

守护进程

 这是我关闭一个会话后打开的另一个会话,打开这个文件后我们可以看到文件在不停的被写入,既没有影响用户与终端的交互,也没有随着会话的关闭而关闭,这样子就实现了一个守护进程。那么怎么结束它呢?我们可以用  ps  aux |  grep  shd来查找守护进程的pid(shd是我的守护进程的名字,守护进程习惯上文件名以d结尾),再用kill杀死它就好啦。