Linux高阶——1027—守护进程

1、守护进程的基本流程

1、父进程创建子进程,父进程退出

守护进程是孤儿进程,但是是工程师人为创建的孤儿进程,低开销模式运行,对系统没有压力

2、子进程(守护进程)脱离控制终端,创建新会话

3、将守护进程中无用的描述符关闭(STDOUT|STDIN)

将STDERROR重定向到文件中,避免屏幕抛出异常信息,避免在使用前台时,后台的守护进程输出到屏幕上

需要把标准出错也要关闭,STDERR_FILENO,标准出错指的是,当使用open函数打开一个不存在文件时,会在终端上显示出来的错误

重定向函数dup和dup2

错误信息会通过STDERR_FILENO将异常抛出到显示器上,因此需要将错误信息重定向,不使用STDERR_FILENO流,而使用输出错误文件的文件描述符fd流

4、将守护进程的工作路径变为根目录

进程默认的工作目录一般为执行程序目录(app)

将默认工作目录(usb)改为目标电脑的根目录,避免工作目录丢失

5、修改进程umask文件权限掩码,变为0002

一般创建文件,文件权限是0664,6表示所有者权限,6表示同组用户权限,4表示其他人权限

一般电脑上初始权限mod为0666,但要与mask掩码0002做取反求与运算,得到0664

开发机的mod初始权限是0666,电脑权限掩码为0002,但目标主机的默认掩码不一定等于0002

将进程掩码改为0002,当进程创建文件时,创建出的文件掩码一定为0002

6、执行守护进程任务(间隔执行|条件触发|定时触发)

7、守护进程退出处理

测试任务

获取时间函数

用户传入数组地址,此函数将字符串时间写入数组中

设定数组中每个元素为time_t类型的变量tp

使用bzero函数初始化数组

使用time函数获取时间种子,赋值给tp

将时间种子tp传入ctime_r函数,计算出当前时间

ctime_r函数最后的返回值带'\n',因此使用tmstrlen(tm)-1='\0'将'\n'去除

复制代码
int Get_time(char* tm) 
{
    time_t tp; 
    bzero(tm,1024);
    tp=time(NULL);
    ctime_r(&tp,tm);
    tm[strlen(tm)-1]='\0';
    return 0;
}

创建进程的工作

复制代码
void daemon_job(void)
{
    int fd;
    if((fd=open("system.log",O_RDWR|O_CREAT,0664))==-1)
    {
        perror("open failed");
    }
    char tm[1024];
    char log_info[4096];
    while(1)
    {
        Get_time(tm);
        sprintf(log_info,"<%s>WARING war informatcion...\n",tm);
        write(fd,log_info,strlen(log_info));
        bzero(log_info,sizeof(log_info));
        bzero(tm,sizeof(tm));
        sleep(3);
    }
}

创建守护进程

复制代码
int create_daemon(void)
{
    pid_t pid;
    int efd;
    efd=open("ERROR_MSG",O_RDWR|O_CREAT,0664);
    pid=fork();
    if(pid>0)
    {
        exit(0);
    }
    else if(pid==0)
    {
        setsid();
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        dup2(efd,STDERR_FILENO);
        chdir("./");
        umask(0002);
        daemon_job();
    }
    else
    {
        perror("fork call failed");
    }
    return 0;
}

总代码

复制代码
#include<stdio.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<errno.h>
#include<signal.h>
#include<pthread.h>
#include<sys/fcntl.h>
#include<string.h>

int Get_time(char* tm) 
{
    time_t tp; 
    bzero(tm,1024);
    tp=time(NULL);
    ctime_r(&tp,tm);
    tm[strlen(tm)-1]='\0';
    return 0;
}

void daemon_job(void)
{
    int fd;
    if((fd=open("system.log",O_RDWR|O_CREAT,0664))==-1)
    {
        perror("open failed");
    }
    char tm[1024];
    char log_info[4096];
    while(1)
    {
        Get_time(tm);
        sprintf(log_info,"<%s>WARING war informatcion...\n",tm);
        write(fd,log_info,strlen(log_info));
        bzero(log_info,sizeof(log_info));
        bzero(tm,sizeof(tm));
        sleep(3);
    }
}

int create_daemon(void)
{
    pid_t pid;
    int efd;
    efd=open("ERROR_MSG",O_RDWR|O_CREAT,0664);
    pid=fork();
    if(pid>0)
    {
        exit(0);
    }
    else if(pid==0)
    {
        setsid();
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        dup2(efd,STDERR_FILENO);
        chdir("./");
        umask(0002);
        daemon_job();
    }
    else
    {
        perror("fork call failed");
    }
    return 0;
}

int main()
{
    create_daemon();
    return 0;
}

创建一个system.log的日志文件,每隔3秒,向日志文件中写入当前系统时间

eg:<系统时间>WARNING,test war message

2、实现Linux操作系统开机启动

shell脚本

脚本池里有许多脚本,每个脚本可以启动一个程序

虚拟机操作系统LINUX OS启动时,会将脚本池里的所有shell脚本对应的程序启动

编写一个shell脚本,让此脚本可以定位并启动守护程序

步骤:

1、将脚本放进系统脚本文件夹/etc/init.d/

2、将自定义脚本通过update-rc.d加入系统脚本池

3、!/bin/bash声明脚本中使用的shell版本

sudo mv start_daemon /etc/init.d/

cd /etc/init.d

sudo update-rc.d shell_name start 99 2.------添加启动

sudo update-rc.d shell_name remove------删除启动

shell脚本------命令的容器,可以将大量命令写入脚本,最后进行批量执行和处理,有了脚本后使用命令更方便

相关推荐
A小辣椒1 天前
TShark:Wireshark CLI 功能
linux
A小辣椒2 天前
TShark:基础知识
linux
AlfredZhao2 天前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao2 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334663 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪3 天前
linux 拷贝文件或目录到指定的位置
linux
大树883 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠3 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质3 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush43 天前
嵌入式linux学习记录十四、术语
linux·嵌入式