说说守护进程

守护进程又称精灵进程(daemon),一般在系统启动时开始,而在系统关闭时终止。没有控制终端,运行在后台。在linux系统中有很多这类进程。

下面说一下如何创建一个守护进程。

(1) 使用umask修改文件的屏蔽字,为文件赋予跟多的权限,因为继承来的文件可能某些权限被屏蔽,从而失去某些功能,如读写。
        (2) 调用fork函数创建一个子进程,而父进程退出。
        (3) 调用settid创建一个新会话,当前进程为会话组长,并且关闭控制终端。
        (4) 修改进程工作目录为根目录,chdir(“/”).
        (5) 关闭不需要的从父进程继承过来的文件描述符。
        (6) 打开/dev/null,null也称黑洞设备,就是写入或读出什么都没有效果。代开这个设备是文件具有0,1,2三个文件描述符,但是对标准输入,标准输出,标准出错的操作都没有效果。这部分内容不是必须的。

下面使用一个例程说一下这个过程。

#include <stdio.h>
        #include <unistd.h>
        #include <sys/types.h>
        #include <stdlib.h>
        #include <sys/resource.h>

int main()
        {

        pid_t pid;
                struct rlimit r;
                int i;

//XXX step 1:set umask
                umask(0);

//XXX setp 2:fork
                if((pid = fork()) < 0)
                {
                        perror("fork");
                        exit(0);
                }
                else if(pid != 0)
                {
                        exit(0);
                }

//XXX step 3:setsid
                setsid();

//XXX step 4:chdir
                chdir("/");

//XXX step 5:close all open file descriptors
                if(r.rlim_max == RLIM_INFINITY)
                {
                        r.rlim_max = 1024;
                } 
                for(i = 0; i < r.rlim_max; i++)
                {
                        close(i);
                }

                while(1)
                {

        }
                return 0;
        }

上面便是一个守护进程的创建过程,可是一些书或网络上写守护进程,会在第三步和第四步之间添加这样一点代码。

        if((pid = fork()) < 0)
                {
                        perror("fork");
                        exit(0);
                }
                else if(pid != 0)
                {
                        exit(0);
                }

很多学生就会问,为什么要创建两次进程呢,这是因为第三步结束后,进程创建了一个新的会话组,并成为会话组长,而会话组长可能获得控制终端,如果获得了控制终端那么或这个进程就不是守护进程了。所以添加了这几句代码,让进程失去会话组长的身份,从而没有获得控制终端的权限。

猜你喜欢

转载自blog.csdn.net/liu0808/article/details/80373542