守护进程理解和实现

2/22/2017来源:ASP.NET技巧人气:1608

守护进程理解和实现

守护进程:浅显一点的认识就是脱离用户终端的后台进程,当我们关闭终端时,该进程也不会退出。举个例子:比如我们远程登录一个linux系统,通过终端运行服务器程序,此时我们关闭终端退出来的时候,我们希望该服务器程序依然运行。此时就需要使该服务器进程是守护进程。

守护进程的实现步骤

创建子进程,父进程退出,子进程成孤儿进程 使子进程成为后天进程。 在子进程中创建新的会话,脱离控制终端 刚开始,一个会话组id对应一个终端,会话组里包含前台进程组和后台进程组。当关闭终端时,会话组里的所有进程都关闭。所以子进程要想脱离终端时,使用setsid()就可创建新的会话组,并且担任该会话组的组长,独立出终端。 改变当前工作目录为根目录 子进程会继承父进程的工作目录,由于在进程运行中,当前目录所在的文件系统是不能卸载的,这对以后使用会造成很多的麻烦。所以需要使用chdir改变子进程的工作目录为根目录。 重设文件权限掩码 文件权限掩码是屏蔽掉文件权限中的对应位。由于使用fork()函数新创建的子进程继承了父进程的文件权限掩码,这就给该子进程使用文件带了很多的麻烦(比如父进程中的文件没有执行文件的权限,然而在子进程中希望执行相应的文件这个时候就会出问题)。因此在子进程中要把文件的权限掩码设置成为0,即在此时有最大的权限,这样可以大大增强该守护进程的灵活性。设置的方法是:umask(0) 关闭文件描述符 子进程会继承父进程的文件描述符,但是守护进程一般又用不到,所以一般全部关闭掉。 守护进程的退出,信号注册 通过kill命令,使守护进程退出,通常需要signal注册信号处理函数,进行退出处理。

示例代码

#include<stdio.h> #include<fcntl.h> #include<sys/stat.h> #include<string.h> #include<sys/types.h> #include<unistd.h> #include<stdlib.h> int main(){ pid_t pid; char *buf="this is a dameon\n"; pid=fork(); if(pid>0){ //创建一个进程用来做守护进程 exit(0); } setsid(); //使子进程独立1.摆脱原会话控制 2.摆脱原进程组的控制 3.摆脱控制中端的控制 chdir("/"); //改变当前工作目录,这也是为了摆脱父进程的影响 umask(0); //重设文件权限掩码 int i; for(i=0;i<1024;i++){ //关闭文件描述符(常说的输入,输出,报错3个文件), close(i); //因为守护进程要失去了对所属的控制终端的联系,这三个文件要关闭 } int fd=open("/tmp/dameon.txt",O_CREAT|O_WRONLY|O_APPEND,0777); if(fd<0){ perror("open"); return -1; } while(1){ write(fd,buf,strlen(buf)+1); sleep(5); } close(fd); }