linux中守护进程又称:后台进程、 精灵进程 、daemon
1.特点:
在后台运行的进程,生命周期长,一般情况下在系统开机的时候启动,在关机的时候结束
2.作用:
周期性的处理某些事情,或者执行某些任务。
3.名词:
进程:PID
父进程:创建子进程的进程PPID
进程组:同类型的进程组成的进程组。PGID
会话组:同类型的进程组成的,SID
如何创建一个守护进程
4.思路:
- 确定它的人物
- 和终端脱离关系
- 确保当前守护进程的依赖目录不被卸载
- 根据当前的检测结果分类提示 msgbox 写日志。
- 考虑从父进程
5.创建守护进程:
5.1.创建子进程,父进程退出
当前子进程不是进程组组长,这样自己就不是进程组的组长
相关函数:fork()
5.2.创建新的会话组(脱离控制终端)。
它创建新的会话组,它是会话组的组长,它是进程组的组长,该组内只有一个进程,该会话组内只有一个进程,并且没有控制终端。
在这里使用的是系统函数setsid()来创建一个新的会话,并且担任该会话组的组长,摆脱原会话的控制==》摆脱原进程的控制==》摆脱原控制终端的控制。
相关函数:setsid();
5.3.切换工作路径
一般切换到,根目录,因为根目录不会被卸载。
相关函数:chdir(“/”);
5.4.更新文件权限掩码
文件权限掩码是屏蔽掉文件权限中的对应位。由于使用fork()函数新创建的子进程继承了父进程的文件权限掩码,这就给该子进程使用文件带了很多的麻烦(比如父进程中的文件没有执行文件的权限,然而在子进程中希望执行相应的文件这个时候就会出问题)。因此在子进程中要把文件的权限掩码设置成为0,即在此时有大的权限,这样可以大大增强该守护进程的灵活性
相关函数: umask(0);
5.5.关闭不需要的文件描述符,等需要的时候再重新打开。
maxFd = getdtablesize();
for(fd =0 ;fd <= maxFd;fd++)
{
close(fd);
}
5.6.做自己的事情
while(1)
{
/* do */
}
5.7.查看守护进程状况:
一般守护进程会在最下面显示。
yuupeng@ubuntu:~/test$ gcc Deamon.c -o my_deamon
yuupeng@ubuntu:~/test$ ./my_deamon /*执行会创建守护进程*/
yuupeng@ubuntu:~/test$ ps axj | head -n1
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
yuupeng@ubuntu:~/test$ ps axj | tail -n5
2 3583 0 0 ? -1 S 0 0:00 [kworker/0:1]
2 3697 0 0 ? -1 S 0 0:00 [kworker/0:0]
1 4041 4041 4041 ? -1 Ss 1000 0:00 ./my_deamon /*守护进程*/
3273 4073 4073 3273 pts/5 4073 R+ 1000 0:00 ps axj
3273 4074 4073 3273 pts/5 4073 S+ 1000 0:00 tail -n5
yuupeng@ubuntu:~/test$ kill 4041 /*退出守护进程进程号:4041*/
yuupeng@ubuntu:~/test$ ps axj | tail -n4 /*再次检查守护进程信息*/
2 3583 0 0 ? -1 S 0 0:00 [kworker/0:1]
2 3697 0 0 ? -1 S 0 0:00 [kworker/0:0]
3273 4082 4082 3273 pts/5 4082 R+ 1000 0:00 ps axj
3273 4083 4082 3273 pts/5 4082 S+ 1000 0:00 tail -n5
yuupeng@ubuntu:~/test$
6.例程
/*守护进程 */
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<string.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/wait.h>
int main()
{
pid_t pid =0;
int fd=0;
int maxFd=0;
char *buf = "yuupeng";
//创建一个子进程,父进程退出
pid = fork();
if(pid < 0)
{
perror("Fork error\n");
return -1;
}else if(pid > 0)
{
exit(0);
}
printf("创建子进程成功");
//创建会话组,只有不是进程组的组长则 setsid(); 才会成功
setsid();
//切换工作路径
chdir("/tmp");
//修改文件权限
umask(0);
//关闭不需要的文件描述符
maxFd = getdtablesize();
for(fd =0 ;fd < maxFd;fd++)
{
close(fd);
}
//做自己的事情
while(1)
{
/*在目录 /tmp 下守护进程会给1.txt创建文件*/
if((fd = open("1.txt",O_CREAT|O_WRONLY|O_TRUNC,0600))<0)
{
printf("Open file error \n");
exit(1);
}
while(1){
/* 循环的给 目录 /tmp/1.txt 这个文件写数据 */
write(fd,buf,strlen(buf));
sleep(1);
}
close(fd);
}
exit(0);
return 0;
}