目录

linux-守护进程

目录

linux-守护进程

1.守护进程(服务|精灵进程)(基本以d结尾,如mysqld):运行周期长,后台运行,不和用户交互

2.守护进程编程流程(主要处理日志信息,让错误直接打印在日志中,并且打印时间):让一个组员进程创建新会话,脱离原有的终端,产生新会话,在新的会话中这个组员的pid就是新会话的sid,同时在新会话中也会产生一个新的组,自己也就是组长进程。这样当上一个会话关闭,这个新的也不会关闭。

https://i-blog.csdnimg.cn/direct/623589dd2375490b9eaf0a60eeda5cdd.png

每打开一个终端都会产生一个会话,每个会话都以打开的首个进程(bash)作为会话首进程,会话首进程的pid标识该会话,每一个命令都会产生一个进程,进程产生的同时就会产生一个进程组fork后有多个进程,第一个进程是组长,这个组以组长的pid标识。(getpid(),getsid()获得会话id,getpgrp()获得组id)

具体流程如下:运行后显示的终端要是个‘?’就代表没有终端

怎么查看日志:拿tail查看 tail -f +名字,可以一直跟踪日志进度

–> 第一个 fork() 通过退出父进程,子进程成为守护进程的候选者。

–>创建一个新的会话,并使当前进程成为该会话的首进程。

–>第二个 fork() 的目的是确保守护进程不会成为会话的首进程

–>将工作目录改为根目录,防止守护进程占用某个文件系统,导致无法卸载。

–>清除文件掩码,确保守护进程创建的文件具有正确的权限。

–>关闭所有打开的文件描述符,避免守护进程占用不必要的资源。

https://i-blog.csdnimg.cn/direct/f36727996b1f45e781cd7ddd541fb191.png

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>//
#include <sys/stat.h>


int main()
{
    __pid_t pid = fork();
    if ( pid != 0 )//先fork,退出父进程,变成组员进程
    {
        exit(0);
    }

    setsid();//创建新会话

    pid = fork();//再次退出父进程-->使得当前子进程失去当前会话首进程和会话进程组组长的身份
    if ( pid != 0 )
    {
        exit(0);
    }

    chdir("/");//更改工作路径到根目录,防止被删除
    umask(0);//清除掩码:为创建文件做准备

    int maxfd = getdtablesize();//进程能打开的文件的文件描述符最大值
    for(int i = 0; i < maxfd; i++ )
    {
        close(i);//关闭所有描述符
    }

    while( 1 )//每5s在当前日志写下当前时间
    {
        time_t tv;
        time(&tv);//获得时间,自1997年到现在多少秒
        FILE* fp = fopen("/tmp/c2404d.log","a");//放在根目录底下/tmp,a为以追加的形式,直接cd /tmp进行查看

        fprintf(fp,"Time is %s",asctime(localtime(&tv)));//localtime(可以转化成年月日小时分钟秒)但为为结构体要转换成字符串
        fclose(fp);
        sleep(5);//每5s打印一次
    }

}