Linux 守护进程
Linux 守护进程
守护进程,也就是通常所说的Daemon进程,是Linux中的后台服务进程。
守护进程常常在系统引导装入时启动,在系统关闭时终止。
编写守护进程
1. 创建子进程,父进程退出
由于守护进程是脱离控制终端的,子进程退出,会造成子进程没有父进程,从而变成一个孤儿进程。就会自动由1 号进程(也就是init 进程)收养它,这样,原先的子进程就会变成init进程的子进程了。
2. 在子进程中创建新会话
由于在调用fork函数时,子进程全盘拷贝了父进程的进会话期、进程组、控制终端。用 setsid
函数可以使进程完全独立出来。
会话组是一个或多个进程组的集合。通常,一个会话开始于用户登录,终止于用户退出。
SYNOPSIS
#include <unistd.h>
pid_t setsid(void);
3. 改变当前目录为根目录
使用fork创建的子进程继承了父进程的当前工作目录。
4. 重设文件权限掩码
设置文件权限掩码为umask(0)
。
5. 关闭文件描述符
用fork函数新建的子进程会从父进程那里继承一些已经打开了的
文件,消耗系统资源。比如,文件描述符为0、1和2的3个文件再也不会用到。关闭方式:
for(i=0;i<MAXFILE;i++)
close(i);
实例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#define MAXFILE 65535
int main()
{
pid_t pc;
int i, fd, len;
char *buf = "This is a Daemon\n";
len = strlen(buf);
/* 1. */
pc = fork();
if(pc < 0){
printf("error fork\n");
exit(1);
}else if(pc > 0){
exit(0);
}
/* 2 */
setsid();
/* 3 */
chdir("/");
/* 4 */
umask(0);
/* 5 */
for(i = 0; i < MAXFILE; i++){
close(i);
}
while(1){
if((fd = open("/tmp/daemon.log", O_CREAT|O_WRONLY|O_APPEND, 0600)) < 0){
perror("open");
exit(1);
}
write(fd, buf, len+1);
close(fd);
sleep(10);
}
}
结果如下:
每10秒打印一次。
xxx@xxx-pc:~/Documents$ cat /tmp/daemon.log
This is a Daemon
This is a Daemon
This is a Daemon
守护进程的日志
使用syslog服务,将程序中的出错信息输入到“/var/log/messages”系统日志文件中。
守护进程在启动时会读一个配置文件“/etc/syslog.conf”。该文件决定了不同种类的消息会发送向何处。
SYNOPSIS
#include <syslog.h>
void openlog(const char *ident, int option, int facility);
void syslog(int priority, const char *format, ...);
void closelog(void);
syslog函数会自动调用openlog,closelog在程序结束时自动调用。实际上简单地输出log,只用调用syslog函数就可以了。