关于守护进程

来源:互联网 发布:bbc动物纪录片知乎 编辑:程序博客网 时间:2024/05/16 15:04
守护进程
    
    守护进程就是后台运行的一种特殊进程。它独立于控制终端且周期性的执行某种任务或等待处理某些发生的事件

    Linux的大多数服务器就是用守护进程实现的。比如,Internet服务器inetd,Web服务器httpd等。

        同时,守护进程完成许多系统任务。比如,作业规划进程crond,打印进程lpd等。

    守护进程的特性:

        1、 后台运行

        2、守护进程必须与其运行前的环境隔离开来。(包括未关闭的文件描述符,控制终端,进程组,会话,工作目录,掩码(umask)等从执行它的父进程中继承下来的东西)

        3、可以在linux系统启动时从启动脚本 /etc/rc.d 中启动,可由作业规划进程 crond 启动, 由用户终端(通常是shell)执行。

    守护进程的编程要点(步骤):

        1、在后台运行

            在进程中调用fork, 使父进程终止,子进程继续。

            使所有工作在子进程中进行

        2、脱离控制终端,创建新会话和进程组

            因为控制终端是从父进程继承而来的,而控制终端是 控制进程(会话首进程) 所持有的,因此我们要脱离这个会话从而摆脱控制

                终端的束缚。 在 第一点 的基础上调用 setsid()

            进程成为新的会话首进程和进程组组长,完全脱离了原来的会话和进程和控制终端。

        3、 关闭文件描述符
            
            继承的打开文件不会用到,浪费系统资源,无法卸载
    
            调用getdtablesize()(返回子进程文件描述符表的项数, 根据描述符的最小值规则,可根据这个返回值关闭所有打开的文件描述符)
    
                返回所在进程的文件描述符表的项数,即该进程打开的文件数目

        4、改变当前的工作目录

            一般更换为根目录(chdir)

            防止占用可卸载的文件系统

        5、重设文件权限掩码

            继承的文件权限掩码。可能修改守护进程创建的文件的存取位

            一般将umask清除(umaks(0))

        6、处理 SIGCHLD信号

            虽然这不是必须的,但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求则需要处理。

            若不处理,逐渐占用系统资源,产生 僵死进程

            若一直等待处理,则影响服务器的并发性能。


#include <stdio.h>#include <string.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>int main(){        pid_t pid;        char *str = "I am a test\n";        int fdcounts;        int i;        int fd;        if((pid=fork()) < 0)        {                perror("rk");                exit(1);        }        else if(pid > 0)                                        //exit the parent                exit(0);        setsid();                                               //create a new session to be independent        fdcounts = getdtablesize();        for(i=0; i<fdcounts; i++)                close(i);                                       //close all the opened descriptor        chdir("/");                                             //change working directory        umask(0);                                               //clear the umask        for(;;)        {                fd = open("/tmp/deamontest",O_WRONLY | O_APPEND | O_CREAT, 0664);                if(fd < 0)                {                        perror("open");                        exit(1);                }                write(fd, str, strlen(str));                close(fd);                sleep(10);                printf("I still have a place for outputing ?\n");        }        return 0;}




运行结果
<pre name="code" class="html">(并无终端输出  I still have a place for outputing ? 这句话)
$ cat /tmp/deamontestI am a testI am a testI am a testI am a testI am a testI am a testI am a testI am a test






    这里就展示了如何建立一个守护进程的过程

0 0