守护进程(daemon)是一类在后台运行的特殊进程,用于执行特定的系统任务。很多守护进程在系统引导的时候启动,并且一直运行直到系统关闭。另一些只在需要的时候才启动,完成任务后就自动结束。
守护进程是一个在后台运行并且不受任何终端控制的进程。这也是守护进程最重要的特点。在Linux下创建守护进程的步骤如下。
- 创建子进程,终止父进程 这是因为守护进程是脱离终端控制的,所以要造成一种在终端里已经运行完的假象,把所有的工作都放在子进程中去完成。父进程退出后,子进程变成孤儿进程。
- 在子进程中创建新会话 这是因为即使子进程已经变成了孤儿进程,但是它始终是被父进程创建出来的,继承了父进程的会话、进程组、控制终端等等。创建了新的会话之后,子进程就脱离原会话的控制,摆脱了原进程组的控制,摆脱了原控制终端的控制。
- 更改当前工作目录为根目录 使用fork创建的子进程也继承了父进程的当前工作目录。由于在进程运行过程中,当前目录所在的文件系统不能卸载,因此,把当前工作目录换成其他的路径,如“/”或“/tmp”等。
- 重设文件掩码 由于通过fork函数创建的子进程继承了父进程的文件掩码,这就给该子进程使用文件带来了诸多的麻烦。因此,把文件创建掩码设置为0,可以大大增强该守护进程的灵活性。
- 关闭文件描述符 用fork新建的子进程会从父进程那里继承一些已经打开了的文件。这些被打开的文件可能永远不会被守护进程读或写,但它们一样消耗系统资源,可能导致所在的文件系统无法卸载。、
下面是在Linux系统下创建守护进程的一个简单示例。
代码语言:javascript复制#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define MAXFILE 65535
int main()
{
int i,fd;
pid_t pid;
char *buf = "create a dameonn";
int len = strlen(buf);
//创建子进程,终止父进程
pid = fork();
if(pid < 0)
{
perror("创建子进程失败");
exit(-1);
}
else if(pid > 0)
{
exit(0);
}
//建立新会话
setsid();
//更改工作目录
chdir("/");
//修改文件掩码
umask(0);
//关闭文件
for(i=0;i<MAXFILE;i )
{
close(i);
}
while(1) //在后台一直运行
{
fd = open("/mnt/hgfs/共享文件夹/Linux环境编程/dameon.log",O_CREAT|O_WRONLY|O_APPEND,0664);
if(fd < 0)
{
perror("open failed");
exit(-1);
}
write(fd,buf,len);
close(fd);
}
return 0;
}
执行以后,我们可以通过ps aux命令在终端看到daemon进程成为了一个守护进程。他的TTY标志是问号(?)。结果如下:
当我们不需要的守护进程的在后台继续执行的时候,可以通过kill -9 pid来杀死它。我们可以查看daemon.log文件的内容如下: