在linux或者unix操作系统中在系统的引导的时候会开启很多服务,这些服务就叫做守护进程。为了增加灵活性,root可以选择系统开启的模式,这些模式叫做运行级别,每一种运行级别以一定的方式配置系统。 守护进程是脱离于终端并且在后台运行的进程。守护进程脱离于终端是为了避免进程在执行过程中的信息在任何终端上显示并且进程也不会被任何终端所产生的终端信息所打断。
守护进程及其特性
守 护进程最重要的特性是后台运行。在这一点上DOS下的常驻内存程序TSR与之相似。其次,守护进程必须与其运行前的环境隔离开来。这些环境包括未关闭的文 件描述符,控制终端,会话和进程组,工作目录以及文件创建掩模等。这些环境通常是守护进程从执行它的父进程(特别是shell)中继承下来的。最后,守护 进程的启动方式有其特殊之处。它可以在Linux系统启动时从启动脚本/etc/rc.d中启动,可以由作业规划进程crond启动,还可以由用户终端 (通常是shell)执行。
守护进程流程处理
- 创建子进程,父进程退出
- 在子进程中创建新会话
- 改变当前目录为根目
- 重设文件权限掩码
- 关闭文件描述符
- 守护进程退出处理
PHP参考
<?php
$fatherFile = fopen('test.txt');
// 重设文件创建掩码
umask( 0 );
// 创建子进程,终止父进程
$pid = pcntl_fork();
if( $pid < 0 ){
exit('fork error.');
} else if( $pid > 0 ) {
exit();
}
// 在子进程中创建新会话
if( !posix_setsid() ){
exit('setsid error.');
}
$pid = pcntl_fork();
if( $pid < 0 ){
exit('fork error');
} else if( $pid > 0 ) {
exit;
}
// 改变工作目录
chdir( '/tmp' );
// 关闭文件描述符
fclose($fatherFile);
C参考
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>
#include <signal.h>
#define MAXFILE 65535
volatile sig_atomic_t _running = 1;
void sigterm_handler(int arg)
{
_running = 0;
}
int main()
{
pid_t pc, pid;
int i, fd, len;
char *buf = "this is a Dameon\n";
len = strlen(buf);
//第一步
pc = fork();
if(pc < 0)
{
printf("error fork\n");
exit(1);
}
else if(pc > 0)
{
exit(0);
}
//第二步
setsid();
pid = fork();//与终端完全脱离[1]
if (pid < 0)
{
perror("fork error");
}
if (pid > 0)
{
exit(0);
}
//第三步
chdir("/");
//第四步
umask(0);
//第五步
for(i = 0;i < MAXFILE; i++)
{
close(i);
}
signal(SIGTERM, sigterm_handler);
while( _running )
{
if((fd = open("/tmp/dameon.log", O_CREAT | O_WRONLY | O_APPEND, 0600)) < 0)
{
perror("open");
exit(1);
}
write(fd, buf, len);
close(fd);
usleep(10 * 1000);//10毫秒
}