【Linux】孤儿进程|守护进程|Shell脚本设置守护进程开机自启

🔥博客主页: 我要成为C++领域大神
🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统
❤️感谢大家点赞👍收藏⭐评论✍️

本博客致力于知识分享,与更多的人进行学习交流

Orphan孤儿进程

父进程先于子进程异常退出,子进程被托管给托管进程,子进程成为活态进程,失去管理,这种进程称为孤儿进程(Orphan Process)。

Ubuntu16.04托管进程为upstart进程,14.04版本托管进程为init进程

孤儿进程是异常进程模型的残留,会影响新进程的创建与使用。这种活态进程的危害是有弹性的,取决于孤儿进程的作业,如果孤儿进程被设置大量频繁的申请占用系统资源,那么这种孤儿进程危害极大。

下面是一个产生孤儿进程的demo程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
#include <sys/fcntl.h>
 

int main()
{
    pid_t pid;
    pid=fork();
    if(pid>0){
        printf("Parent PID:%d\n",getpid());
        sleep(10);
        exit(0);
    }else if(pid==0){
        printf("Child PID:%d PPID:%d\n",getpid(),getppid());
        sleep(11);
        printf("Child PID:%d PPID:%d\n",getpid(),getppid());
    }else{
        perror("fork call failed");
        exit(0);
    }
	return 0;
}

1543号进程为upstart托管进程

这种情况下,子进程一直打印未退出,是否影响终端的命令输入?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
#include <sys/fcntl.h>
 

int main()
{
    pid_t pid;
    pid=fork();
    if(pid>0){
        printf("Parent PID:%d\n",getpid());
        sleep(10);
        exit(0);
    }else if(pid==0){
        printf("Child PID:%d PPID:%d\n",getpid(),getppid());
        while(1){
        printf("Child PID:%d PPID:%d\n",getpid(),getppid());
	sleep(2);
	}
    }else{
        perror("fork call failed");
        exit(0);
    }
	return 0;
}

不影响,因为在终端打印是标注输出文件描述符,输入命令执行是标准输入文件描述符

如何解决孤儿进程带来的问题

守护进程Daemon Process

什么是守护进程?

守护进程是孤儿进程的一种特殊情况,开发者创建父子进程模型,让父进程退出,子进程变为守护进程。是一种人为的孤儿进程。

守护进程(Daemon Process)是在计算机系统中以后台方式运行的特殊进程,经典的后台服务进程。持续执行在后台完成特定服务,不干预前台任务。不依赖于终端或会话,它独立于终端控制并在系统级别执行特定的任务。

普通的软件进程随用户持续,生命周期较短。守护进程的生命周期较长,开机启动关机结束,持续服务于平台。

守护进程不能持续占用系统资源(CPU、内存等),长时间处于低开销模式。

守护进程的工作模式

间隔执行(sleep)、定时启动、条件触发、低销模式(大多数时间进程处于睡眠态)

后台服务进程不允许访问前台,不能使用标准输入标准输出,而标准输出需要使用,但是不能让其打印在终端,所以要使用(dup2实现重定向)。

如何查看守护进程

通过命令ps axj,可以查看系统中的所有进程。其中,参数a指定要列出所有用户的进程,而不仅仅是当前用户的进程;参数x包括列出所有无控制终端的进程,而不仅仅是有控制终端的进程;参数j则能够提供与作业控制相关的信息。

这个命令的输出包含了许多字段,包括PID、PPID、PGID、SID、TTY、STAT、TIME、COMMAND等。其中,PID是进程的唯一标识符;PPID是父进程的PID;PGID是进程所属的进程组ID;SID是进程所属的会话ID;TTY是进程所使用的终端设备;STAT是进程状态;TIME是进程运行的时间;COMMAND是进程正在执行的命令。

由于参数j还提供了作业控制相关的信息,因此此命令的输出还包括作业ID(JID)、进程对应的作业名(JOBNAME)以及作业的状态(STATE)等信息。这些信息对于理解进程和作业之间的关系以及系统运行情况非常有用。

凡是TPGID一栏写着 -1 的都是没有控制终端的进程,也就是守护进程;

守护进程的实现流程

在过去的软件开发中,搭建服务都是使用U盘挂载的,进程的工作路径都是在USB中,所以服务进程在初次启动后,需要更改进程路径到主机根目录下,对USB解除占用。否则U盘拔下来,进程也将退出。

关于什么是会话,子进程如何话脱离终端创建会话,可以看我这一期博客:【操作系统】进程组Group|进程会话Session 

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

void Daemon_Bussiness(){
    int fd=open("time.logg",O_RDWR,0664);
    if(fd==-1){
        perror("open failed");
    }
    char buffer[80];
    struct tm*local;
    int nLength;
    while(1){
        time_t now=time(NULL);//生成时间种子
        local=localtime(&now);
        nLength=strftime(buffer,sizeof(buffer),"%Y-%m-%d %H-%M-%S\n",local);
        write(fd,buffer,nLength);
        sleep(3);
    }
}
void Daemon_Create(){
    //1、创建子进程,父进程退出
    pid_t pid;
    pid=fork();
    if(pid>0){
        printf("Parent PID:%d is Running\n",getpid());
        sleep(2);
        printf("Parent is Exiting\n");
        exit(0);
    }
    else if(pid==0){
    //2、创建新会话,脱离终端
    printf("Child PID:%d is Running,PPID:%d,SID:%d\n",getpid(),getppid(),getsid(getpid()));
    sleep(2);
    printf("Child PID:%d,SID:%d,变为了守护进程\n",getpid(),setsid());
    //3、改变工作路径
    chdir("./");
    //4、修改进程umask
    umask(0002);
    //5、关闭无用描述符
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    //重定向标准出错符
    int fd=open("ERROR.log",O_RDWR|O_CREAT,0664);
    dup2(fd,STDERR_FILENO);
    //6、执行守护进程业务
    Daemon_Bussiness();
    //7、守护进程退出处理(由于本demo程序中没有申请内存,所以不涉及到这里)
    exit(0);
    }else{
        perror("fork call failed");
    }

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

运行结果:

运行可执行文件后,生成了守护进程。每隔3秒增加一行日志

杀死守护进程后,日志不再增加。

关闭终端后,守护进程仍在后台不停运行。

关于重定向标准出错流:

当我们尝试只读方式打开一个不存在的文件,会通过标准出错向我们报错,正常标准出错是打印到终端上的,在我们重定向之后,将错误打印到了错误日志里。

shell脚本

Shell脚本是用于自动化任务的一种编程脚本,通常运行在UNIX和Linux操作系统的Shell终端中。Shell脚本可以执行命令行中的一系列命令,以便自动化系统管理任务、批处理作业和其他重复性工作。

Shell 脚本的特点

  1. 可执行性:Shell脚本文件通常通过添加执行权限来运行。
  2. 解释执行:Shell脚本由Shell解释器逐行解释执行,而不是编译成二进制代码。
  3. 简洁性:适合编写简短的脚本以完成特定任务。
  4. 强大的系统管理功能:能够调用操作系统的各种功能,包括文件操作、进程管理、网络通信等。

创建和运行Shell脚本

#!/bin/bash

ls -l
date
赋予执行权限并运行脚本
sudo chmod 0775 shell_start.sh

运行脚本

./shell_start.sh

运行结果:

成功执行了ls -ldate两个命令

通过shell脚本设置守护进程开机自启动

开机自启动的实现原理

系统初始化脚本(SysV init)

启动级别脚本:传统的SysV init系统使用不同的运行级别(runlevels)来启动相应的服务。启动脚本通常位于 /etc/init.d 目录中

配置方法:可以通过在相应的运行级别目录中创建复制启动脚本

sudo ln -s /etc/init.d/myscript /etc/rc.d/rc3.d/S99myscript

设置守护进程开机自启

1、将其他脚本的启动块信息复制到自定义脚本中

2、将自定义脚本复制到/etc/inti.d/目录

3、通过命令将脚本加入开机启动序列sudo update-rc.d shell start 99 2.

通过命令删除开机启动序列中的脚本sudo update-rc.d shell remove

下面将写一个脚本设置我们创建的守护进程开机自启动

将启动块信息添加到我们脚本中

脚本开始运行后跳转到我们的可执行文件所在目录,然后执行创建守护进程的文件。

将脚本复制到启动序列目录下

通过命令将脚本加入开机启动序列sudo update-rc.d shell_start start 99 2.

重启一下查看是否设置成功。

设置成功!

 


http://www.niftyadmin.cn/n/5534596.html

相关文章

NAPI篇【4】——NAPI应用点亮一个LED

OpenHarmony的NAPI功能为开发者提供了JS与C/C不同语言模块之间的相互访问&#xff0c;交互的能力&#xff0c;使得开发者使用C或者C语言实现应用的关键功能。如操作开发板中某个GPIO节点的状态&#xff08;OpenHarmony并没有提供直接操作GPIO口状态的API&#xff09;&#xff0…

复习2-20240624

vscode 使用 Javabean &#xff08;封装性&#xff09; public class Demo01 {/*1.原则 &#xff1a; 字母 数字 $ _ 中文 除了 这五个 其它都不可以2. 细则 &#xff1a; 数字 不能 开头%hbviunh &hfiureh )nhjrn 7487j -ni hbiu tgf hi…

[经验] candy是什么意思英语翻译 #笔记#其他#职场发展

candy是什么意思英语翻译 1、candy的意思 Candy是英语中的一个词汇&#xff0c;意思是糖果、糖果制品。Candy意为果脯的意思也不是很常见。 糖果是一种富含糖分的食品&#xff0c;主要由砂糖、粘合剂和食用色素等组成。糖果的种类可以很多&#xff0c;有硬糖、软糖、巧克力、…

LabVIEW与3D相机开发高精度表面检测系统

使用LabVIEW与3D相机开发一个高精度表面检测系统。该系统能够实时获取三维图像&#xff0c;进行精细的表面分析&#xff0c;广泛应用于工业质量控制、自动化检测和科学研究等领域。通过真实案例&#xff0c;展示开发过程中的关键步骤、挑战及解决方案&#xff0c;确保系统的高性…

ArcGIS查找相同图斑、删除重复图斑

​ 点击下方全系列课程学习 点击学习—>ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放 点击学习——>遥感影像综合处理4大遥感软件ArcGISENVIErdaseCognition 这次是上次 今天分享一下&#xff0c;很重要却被大家忽略的两个工具 这两个工具不仅可以找出属性…

初学51单片机之PWM实例呼吸灯以及遇到的问题(已解答)

PWM全名Pulse Width Modulation中文称呼脉冲宽度调制 如图 这是一个周期10ms、频率是100HZ的波形&#xff0c;但是每个周期内&#xff0c;高低电平宽度各不相同&#xff0c;这就是PWM的本质。 占空比是指高电平占整个周期的比列,上图第一个波形的占空比是40%&#xff0c;第二个…

Windows Server 2022 中文版、英文版下载 (updated Jun 2024)

Windows Server 2022 中文版、英文版下载 (updated Jun 2024) Windows Server 2022 x64, Version 21H2 请访问原文链接&#xff1a;https://sysin.org/blog/windows-server-2022/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.o…

【全资料】信息化建设全套资料获取(原件+实际项目参考)

软件开发从需求调研到项目验收需要一系列文档的支持&#xff0c;这些文档在项目的各个阶段发挥着重要的作用。本文将详细介绍这些文档及其作用。 一、需求调研 在软件开发的前期&#xff0c;进行需求调研是非常重要的。需求调研的主要目的是了解用户需求&#xff0c;包括功能需…