即日起在codingBlog上分享您的技术经验即可获得积分,积分可兑换现金哦。

守护进程(Daemon)

编程语言 ADDw1 20℃ 0评论
守护进程(精灵进程):独立于控制终端,不能直接和用户交互,不受用户登录注销的影响的一种进程。
  • 守护进程特点:

    • 独立于控制端(不受控制端的影响)
    • 自成进程组
    • 自成回话
    • 本身是孤儿进程(fork之后父进程退出),所以父进程为init(孤儿进程都被1号进程收养)
    • 守护进程通常采用d结尾,例如:Internet服务器inted;Web服务器httpd;acpid电源管理;sshd远程登录
  • 守护进程一些应用场景:

    • Linux的大多服务器使用Linux守护进程实现的;
    • 作业规划进程(crond)

守护进程的创建
  • 调用umask设置屏蔽字为0(如果不设置创建文件是权限可能会有一定的影响)
  • 创建子进程(fork),父进程退出;

    • 父进程创建的子进程与父进程不属于同一作业,父进程退出表示该作业已执行完
    • 创建的子进程是第二个进程,保证了子进程不是组长进程
  • 调用setsid函数创建一个新会话;

    setsid函数:

    #include


    pid_t setsid(void)



    返回值:成功返回新建session的ID,出错返回-1;


    调用该函数的进程不能是进程组的Leader,否则返回-1;

  • 将当前工作目录更改为根目录

    • 因为根目录一般是不会删除的,而其他的目录极有可能会被删除,工作目录都被删除了,当然运行的作业也就不了了之了
  • 关闭文件描述符

    • 前面我们提到守护进程不能直接和用户交互,即没有标准输入,输出等,所以文件描述符不在需要
  • 忽略SIGCHLD信号

代码(fork一次)
#include
#include
#include
#include
#include
#include

void mydaemon()
{
    int i;
    pid_t id ;

    umask(0);//设置屏蔽字

    id = fork();//创建子进程
    if(id < 0)
    {
        printf("create error");
    }else if(id >0)
    {
        exit(0);//父进程退出
    }

    setsid();//新建session

    i = chdir("/");//更改当前目录为根目录
    //sussess 0
    if(i<0)
    {
        printf("change error");
    }

    close(0);//关闭文件描述符
    close(1);
    close(2);

    signal(17,SIG_DFL);//屏蔽SIGCHLD信号
}

int main()
{
    mydaemon();
    while(1)
    {
        sleep(1);
    }
    return 0;
}

程序运行:


这里写图片描述


fork 1 次与 2 次
  • 首先分析前面用到的setsid函数

    • 调用setsid函数后,创建一个新的session,当前进程成为session的 Leader,即当前进程的ID就是session的ID;
    • 也创建一个新的进程组,当前进程成为进程组的Leader,组ID即当前进程ID;
    • 当前进程失去原有的控制端,成为一个无控制端的进程
  • 上面的分析,调用完setsid函数后,当前进程成为会话首进程(控制进程),会话首进程能够建立与终端的连接,后序如果再打开终端,有可能就会建立连接;所以再次fork保证子进程不是会话首进程
//fork两次代码
#include
#include
#include
#include
#include
#include
#include

void mydaemon()
{
    int i;
    pid_t id ;

    umask(0);

     id = fork();
    if(id < 0)
    {
        printf("create error");
    }else if(id >0)
    {
        exit(0);
    }

    setsid();

//第二次fork
    id = fork();
    if(id < 0)
        printf("create error");
    else if(id >0)
        exit(0);
    i = chdir("/");

    //sussess 0
    if(i<0)
    {
        printf("change error");
    }

    close(0);
    close(1);
    close(2);

    signal(17,SIG_DFL);
}

int main()
{
    mydaemon();
    daemon(0,0);//调用系统的
    while(1)
    {
        sleep(1);
    }
    return 0;
}

Linux标准Daemon
 #include 
 int daemon(int nochdir, int noclose);
//第一个参数:nochdir 如果为0,则改变当前工作目录为根目录
//第二个参数:noclose 如果为0,关闭文件描述符

转载请注明:CodingBlog » 守护进程(Daemon)

喜欢 (0)or分享 (0)
发表我的评论
取消评论

*

表情