• 守护进程详细解读


    守护进程概念

    守护进程也称精灵进程,是运行在后台的一种特殊进程。他独立于终端并且周期性执行某种任务或者等待某件事情的发生。守护进程是一种很有用的进程。比如很多的服务器都是以次方是运行在后台,等待客户端连接并处理相关问题的。

    系统中守护进程通常以d结尾标识。

    创建守护进程关键的一步是调用setsid函数创建一个新的会话,并使之称为控制进程。

    注:调用setsid创建守护进程的当前进程不得是进程组的leader,否则返回-1;保证这个条件的方式是:我们在当前进程进行fork生成子进程,父进程直接退出,子进程调用setsid就可以了。

    成功调用setsid函数的结果是:

    1。创建一个新的会话,并且当前进程称为leader,当前进程id为会话id

    2。创建一个新的进程组,当前进程是进程组的leader,当前进程id就是进程组id

    3。如果当前进程原本有一个控制终端,那么他失去这个终端称为一个没有终端控制的进程。

    创建守护进程

    1调用umask将文件屏蔽字设置为0

    2调用fork,父进程退出

    3调用setsid创建会话:结果1调用进程成为会话首进程,2调用进程成为进程组组长,3调用进程没有控制终端

    4将当前目录更改为根目录

    5关闭不必要的文件描述符

    6忽略SIGCHID信号

    生成守护进程代码

    #include <signal.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <stdio.h>
    #include <unistd.h>
    
    void my_daemon()
    {
        int i;
        int fd0;
        pid_t pid;
        struct sigaction sa;
        umask(0); //设置文文件掩码为0
        if( (pid = fork()) < 0 )
        {
    
        }else if (pid != 0)
        {
            exit(0); //终止止父父进程
        }
        setsid(); //设置新会话
        sa.sa_handler = SIG_IGN;
        sigemptyset(&sa.sa_mask);
        sa.sa_flags = 0;
        if( sigaction(SIGCHLD, &sa, NULL ) < 0 )
        { // 注册子子进程退出忽略信号
            return;
        }
        if( (pid = fork())<0)
        {
         //再次fork,终止止父父进程,保持子子进程不是话首首进程,从而而保证后续    不会在和其他终端关联
            printf("fork error!
    ");
            return;
        }else if( pid != 0)
        {
            exit(0);
        }
        if( chdir("/") < 0 )
        {//更改工工作目目录到根
            printf("child dir error
    ");
            return;
        }
        close(0);
        fd0 = open("/dev/null", O_RDWR); // 关闭标准输入入,重定向所有标准(输入入输出错误)    到/dev/null
        dup2(fd0, 1);
        dup2(fd0, 2);
    }
    int main(int argc, char const *argv[])
    {
        my_daemon();
        while(1)
            sleep(1);
        return 0;
    }

    注:以上代码,是根据定义方式,自己实现的守护进程设置过程。

    #include <stdio.h>
    #include <unistd.h>
    
    int main(int argc, char const *argv[])
    {
        daemon(0,0);
        while(1);
        return 0;
    }

    这个则是系统中提供的设置守护进程的函数。

    由图我们可以看到,守护进程是脱离终端的。

  • 相关阅读:
    2021.07.11 【ABAP随笔】采购订单Message输出打印
    项目管理43210学习笔记
    Rails跳过回调方法
    树莓派接USB温湿度传感器(python)
    Visual Studio2019安装时报错Microsoft.Net.4.7.2.FullRedist的解决方法
    微信浏览器中H5使用wx-open-launch-app打开第三方APP
    Linux系统使用qq邮箱在线发送邮件
    LRU工程实现源码(一):Redis 内存淘汰策略
    Android Studio解决Build Log出现乱码问题
    git新拉取项目
  • 原文地址:https://www.cnblogs.com/lang5230/p/5697733.html
Copyright © 2020-2023  润新知