守护进程也称为精灵进程,是孤儿进程中的一种,主要作用是在系统后台运行且不干扰其他进程的进程,比如很多后台的系统检测进程,一直在后台默默的实时检测着电脑的各个数据,现在我们就通过自己写守护进程实现往一个文件中不断的输入信息来进行模拟。
创建守护进程主要有五个步骤:
1:创建子进程,并退出父进程
2:创建新会话
3:修改工作目录
4:设置权限掩码
5:关闭其他文件描述符
1:创建子进程我们使用fork函数,退出父进程的目的是使子进程成为一个孤儿进程,脱离父进程的管控,但其实还没有完全的脱离,因为子进程在创建时虽然复制了父进程的代码区和变量区等,但是还有一个内核区是二者共享。具体操作如下:
pid_t p=fork();
if(p<0)
{
perror("fork failed\n");
exit(-1);
}
else if(p==0)
{
}
else //父进程退出
{
exit(0);
}
2 :为子进程设置新的会话组,使其成为会话组组长,从而彻底摆脱父进程的影响(到这儿其实一个最简单的守护进程已经创建完成,我们可以运行后通过ps ajx命令查看对应进程的TPGID值是否为-1,是就代表创建成功)
setsid(); //为子进程创建新会话
3:修改子进程工作目录,既然是守护进程就需要不断在后台运行,不要被别人轻易打断或杀死,所以我们将其工作目录修改为根目录,通过chdir函数。
chadir("/"); //更改工作目录为根目录
4:修改权限掩码
使用umask函数
umask(0);
5:关闭其余文件描述符
文件描述符是非负整数,一般当系统打开时会占用0,1,2这三个文件描述符,将其关闭即可
for(int i=0;i<3;i++)
close(i);
到此一个完整的守护进程创建完成,现在我们让其将字符"hello world",不断写入到data.txt文件中
#include <strings.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
pid_t p=fork();
if(p<0)
{
perror("fork failed\n");
exit(-1);
}
else if(p==0) //子进程
{
setsid();
umask(0);
for(int i=0;i<3;i++)
close(i);
int fd=open("data.txt",O_RDWR);
while(1)
{
sleep(2); //每隔两秒就像文件中写入
write(fd,"hello world",11);
}
}
else //父进程
{
exit(0);
}
return 0;
}
看效果:
执行程序后,隔一段时间对data.txt 文件进行查看发现其大小逐渐变大,这是由于我们编写的守护进程在后台不断地运行,在data.txt文件中一直进行写入操作,再打印data.txt一看都是hello world 证明成功,那既然守护进程编写完了一直运行占用内存怎么办,直接将其杀死即可,先使用ps aux查看进程,找到守护进程的名称,找到对应的进程号
使用 sudo kill -9 +进程号 将其杀死.再使用ps aux查看发现已被清除