使用香橙派学习 Linux的守护进程
Q:什么是守护进程
A:Linux Daemon(守护进程)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行 某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个用户程序提供服务。Linux系统的大多数服务器就是通过守护进程实现的。常见的 守护进程包括系统日志进程syslogd、 web服务器httpd、邮件服务器sendmail和数据库服务器 mysqld,守护进程的名称通常以d结尾
守护进程的基本特点
- 生存周期长(非必须),一般操作系统启动的时候就启动,关闭的时候关闭
- 守护进程和终端无关联,也就是他们没有控制终端,所以当控制终端退出,也不会导致守护进程退出
- 守护进程是在后台运行,不会占着终端,终端可以执行其他命令
- 一个守护进程的父进程是init进程,因为它真正的父进程在fork出子进程后就先于子进程exit退出了,所以它是一个由init继承的孤儿进程
linux操作系统本身是有很多的守护进程在默默执行,维持着系统的日常活动。大概30-50个
输入“ps -elf”指令, 显示系统中所有进程的列表,包括其他用户的进程(-ef), 并用长格式显示(-l)
ps -aux 也可以显示这些进程,只不过显示的内容不大一样,比如-aux还会显示进程的状态,CPU和内存显示情况
其中:
- ppid = 0:内核进程,跟随系统启动而启动,生命周期贯穿整个系统
- cmd列名带“ [ ] ”这种,叫内核守护进程
- 老祖init(就是CMD列第一个):也是系统守护进程,它负责启动各运行层次特定的系统服务;所以很多进程的PPID是init,也负责收养孤儿进程
- cmd列中名字不带“ [ ] ”的这种,叫普通守护进程(用户集守护进程)
守护进程和后台进程的区别
- 守护进程和终端不挂钩;后台进程能往终端上输出东西(和终端挂钩)
- 守护进程关闭终端时不受影响,守护进程不会随着终端的退出而退出
Q:如何启动后台进程?
A: 可以选择在执行语句后加上“ &”(空格加&),意思是后台运行
守护进程的开发方式
使用damon函数结合两个C库的时间函数来实现一个“每隔10秒向/home/orangepi/daemon.log写入当前时间”的守护进程
damon()函数
#include <unistd.h>
int daemon(int nochdir, int noclose);
- nochdir:为0时表示将当前目录更改至“/”
- noclose:为0时表示将标准输入、标准输出、标准错误重定向至“/dev/null”
- 返回值: 成功则返回0,失败返回-1
C库函数——asctime()
char *asctime(const struct tm *timeptr)
- 返回一个指向字符串的指针,它代表了结构 struct timeptr 的日期和时间
C库函数——localtime()
struct tm *localtime(const time_t *timer)
- 使用 timer 的值来填充 tm 结构。 timer 的值被分解为 tm 结构,并用本地时区表示
struct tm {int tm_sec; //秒,范围从 0 到 59int tm_min; //分,范围从 0 到 59int tm_hour; //小时,范围从 0 到 23int tm_mday; //一月中的第几天,范围从 1 到 31int tm_mon; //月份,范围从 0 到 11int tm_year; //自 1900 起的年数int tm_wday; //一周中的第几天,范围从 0 到 6int tm_yday; //一年中的第几天,范围从 0 到 365int tm_isdst; //夏令时 };
time_daemon.c:
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include <stdbool.h>static bool flag = true;void handler(int sig)
{printf("I got a signal %d\nI'm quitting.\n", sig);flag = false; //当检测到退出信号时,将flag置为false,使得main中的while退出循环
}int main()
{time_t t;int fd;//创建守护进程if(-1 == daemon(0, 0)){printf("daemon error\n");exit(1);}//设置信号处理函数//由于守护进程的标准输入、标准输出、标准错误都被重定向到了“/dev/null”,所以影响这个进程的方式只能是信号struct sigaction act; //这里选择使用sigaction函数,定义sigaction结构体act.sa_handler = handler; //但是却给sa_handler赋值而不是sa_sigaction,所以还是相当于使用了signal函数sigemptyset(&act.sa_mask); //将信号集清空act.sa_flags = 0;if(sigaction(SIGQUIT, &act, NULL)) //和上面所说一样,由于没有定义sa_sigaction,所以实现的效果就和signal函数一样,即收到“SIGQUIT”信号的时候执行handler函数{printf("sigaction error.\n");exit(0);}//进程工作内容while(flag){fd = open("/home/orangepi/daemon.log", O_WRONLY | O_CREAT | O_APPEND,0644); //只写打开(O_WRONLY);文件不存在就创建(O_CREAT);每次写都加到文件的尾端(O_APPEND),主用户可读可写(6),其他用户只能读(4)if(fd == -1){printf("open error\n");}t = time(0); //类似初始化char *buf = asctime(localtime(&t)); //localtime将t分解为tm结构,asctime将tm结构解析成时间的字符串write(fd, buf, strlen(buf));close(fd);sleep(10); //每隔10S写入一次}return 0;
}
实现效果:
编译并运行:
此时看起来什么都没有发生,但其实守护进程已经开始跑起来了,可以使用“ps -ef|grep a.out” 指令来验证:
可见,8412就是这个守护进程的PID号(8472是grep的,可以无视)
同时"cd"到根目录下,并“ls”:
出现了这个“daemon.log”的文件
然后此时调用SIGQUIT来结束这个守护进程并验证:
成功退出!最后打开daemon.log:
可见,时间信息确实不断的追加打印到了这个文件!并且,只要不调用SIGQUIT,哪怕关掉终端也不会结束运行,只有系统关闭才会关闭。
且守护进程一般是开机自启的,实现这一点可以通过“sudo vi /etc/rc.local”,然后添加守护进程的绝对路径来实现:
- 注意,这里的路径应该是可执行文件的绝对路径,而不是C文件的绝对路径,所以需要再次编译一下C文件起一个名字
- 且如果想在这个文件下写多个路径,直接分多行写就可以
- 对于非守护进程,如果也想写入文件进行开机自启,可以选择在路径后加上“ &”(空格加&),意思是后台运行
保存退出后,执行“sudo reboot” 重新启动!
重新启动后,使用“ps -ef|grep time_daemon” 指令来查看是否开机自启:
可见,成功实现了开机自启!此时同样输入“sudo kill -3 2331” 来关闭这个守护进程,然后打开daemon.log:
可见,在之前的基础上,又追加写入了很多次的时间信息!
相关文章:

使用香橙派学习 Linux的守护进程
Q:什么是守护进程 A:Linux Daemon(守护进程)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行 某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个…...

数据治理-数据仓库和商务智能
数据仓库的作用 减少数据冗余,提高信息一致性,让企业能够利用数据做出更优决策的方法,数据仓库是企业数据管理的核心。 业务驱动因素 运营支持职能、合规需求(历史数据响应)和商务智能活动(主因࿱…...

CH2--x86系统架构概览
2.1 OVERVIEW OF THE SYSTEM-LEVEL ARCHITECTURE 图中的实线箭头表示线性地址,虚线表示段选择器,虚线箭头表示物理地址 2.1.1 Global and Local Descriptor Tables 全局描述符表 (GDT) GDT是一个全局的段描述符表,它存储在系统内存中的一个固…...

Immutable.js API 简介
Immutable-js 这个库的实现是深拷贝还是浅拷贝?immutable 来源immutable.js三大特性: 持久化数据结构结构共享惰性操作 Immutable.js 的几种数据类型 immutable 使用 使用 npm 安装 immutable: 常用API介绍 MapListList.isList() 和 Map.isMa…...

HLSL 入门(一)
HLSL High Level Shader Language 高级着色语言,是Direct3D中用来编写Shader的语言。其语法类似于C语言。 虽然其主要作用是用来编写例如顶点着色器,像素着色器。但本质是对图形并行管线进行编程,因此也能用来编写用于计算的着色器ÿ…...

【Docker】挂载数据卷
一、Docker数据卷说明及操作 在Docker中挂载数据卷是一种将数据持久化保存的方法,以便容器之间或容器与主机之间共享数据。以下是如何在Docker中挂载数据卷的步骤: 1、创建数据卷 首先,您需要创建一个数据卷。可以使用以下命令创建一个数据卷…...

[技术干货]spring 和spring boot区别
Spring 和 Spring Boot 都是 Java 框架,用于构建企业级应用程序。Spring 是一个完整的框架,提供各种功能,包括依赖注入、事务管理、数据访问、Web 开发等。Spring Boot 是一个基于 Spring 的框架,旨在简化 Spring 应用程序的开发和…...

【hudi】数据湖客户端运维工具Hudi-Cli实战
数据湖客户端运维工具Hudi-Cli实战 help hudi:student_mysql_cdc_hudi_fl->help AVAILABLE COMMANDSArchived Commits Commandtrigger archival: trigger archivalshow archived commits: Read commits from archived files and show detailsshow archived commit stats: …...

RK3588 添加ROOT权限
一.ROOT简介 ROOT权限是Linux和Unix系统中的超级管理员用户帐户,该帐户拥有整个系统的最高权利,可以执行几乎所有操作。ROOT就是获取安卓系统中的最高用户权限,以便执行一些需要高权限才能执行的操作(包括卸载系统自带程序、刷机、备份、还原…...

【云原生】k8s-----集群调度
目录 1.k8s的list-watch机制 1.1 list-watc机制简介 1.2 根据list-watch机制,pod的创建流程 2.scheduler的调度策略 2.1 scheduler的调度策略简介 2.2 Scheduler预选策略的算法 2.3 Scheduler优选策略的算法 3. k8s中的标签管理及nodeSelector和nodeName的 调…...

一键集成prometheus监控微服务接口平均响应时长
一、效果展示 二、环境准备 prometheus + grafana环境 参考博文:https://blog.csdn.net/luckywuxn/article/details/129475991 三、导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter...

2023/9/13 -- C++/QT
作业: 1> 将之前定义的栈类和队列类都实现成模板类 栈: #include <iostream> #define MAX 40 using namespace std;template <typename T> class Stack{ private:T *data;int top; public:Stack();~Stack();Stack(const Stack &ot…...

mybatis mapper.xml转建表语句
从网上下载了代码,但是发现没有DDL建表语句,只能自己手动创建了,感觉太麻烦,就写了一个工具类 将所有的mapper.xml放入到一个文件夹中,程序会自动读取生成建表语句 依赖的jar <dependency><groupId>org.d…...

封装使用Axios进行前后端交互
Axios是一个强大的HTTP客户端,用于在Vue.js应用中进行前后端数据交互。本文将介绍如何在Vue中使用Axios,并通过一个企业应用场景来演示其实际应用。 Axios简介 公众号:Code程序人生,个人网站:https://creatorblog.cn A…...

SOA、分布式、微服务
SOA: SOA是一种软件设计架构,用于构建分布式系统和应用程序。它将应用程序拆分为一系列松耦合的服务,这些服务通过标准化的接口进行通信,并能够以可编程方式组合和重用。SOA的目标是提高系统的灵活性、可扩展性和可维护性。 特点&…...

json数据传输压缩以及数据切片分割分块传输多种实现方法,大数据量情况下zlib压缩以及bytes指定长度分割
json数据传输压缩以及数据切片分割分块传输多种实现方法,大数据量情况下zlib压缩以及bytes指定长度分割。 import sys import zlib import json import mathKAFKA_MAX_SIZE 1024 * 1024 CONTENT_MIN_MAX_SIZE KAFKA_MAX_SIZE * 0.9def split_data(data):"&q…...

移动端APP测试-如何指定测试策略、测试标准?
制定项目的测试策略是一个重要的步骤,可以帮助测试团队明确测试目标、测试范围、测试方法、测试资源、测试风险等,从而提高测试效率和质量。本篇是一些经验总结,理论分享。并不是绝对正确的,也欢迎大家一起讨论。 文章目录 一、测…...

【Redis】深入探索 Redis 主从结构的创建、配置及其底层原理
文章目录 前言一、对 Redis 主从结构的认识1.1 什么是主从结构1.2 主从结构解决的问题 二、主从结构创建2.1 配置并建立从节点2.2.1 从节点配置文件2.2.2 启动并连接 Redis 主从节点2.2.3 SLAVEOF 命令2.2.4 断开主从关系 2.2 查看主从节点的信息2.2.1 INFO REPLICATION 命令2.…...

CSS 滚动驱动动画 scroll-timeline ( scroll-timeline-name ❤️ scroll-timeline-axis )
scroll-timelinescroll-timeline-name❤️scroll-timeline-axis 解决问题语法 animation-timeline-nameanimation-timeline-axis scroll-timeline ( scroll-timeline-name ❤️ scroll-timeline-axis ) 在 scroll() 的最后我们遇到了因为定位问题导致滚动效果失效的情况, 当…...

9.19号作业
2> 完成文本编辑器的保存工作 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QFontDialog> #include <QFont> #include <QMessageBox> #include <QDebug> #include <QColorDialog> #include <QColor&g…...

Mybatis学习笔记9 动态SQL
Mybatis学习笔记8 查询返回专题_biubiubiu0706的博客-CSDN博客 动态SQL的业务场景: 例如 批量删除 get请求 uri?id18&id19&id20 或者post id18&id19&id20 String[] idsrequest.getParameterValues("id") 那么这句SQL是需要动态的 还…...

element表格 和后台联调
1.配置接口 projectList:/api/goods/xxx,//产品列表2.请求接口(get请求默认参数page) // 产品列表 pageprojectList(params){return axios.get(base.projectList,{params})}3.获取数据 直接放到created里边去了 刷新页面就可以看到 async projectList(page){let res await t…...

基于SSM的智慧城市实验室主页系统的设计与实现
末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用Vue技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…...

怒赞,阿里P8推荐的Java面试宝典:41个专题PDF(史上最全+面试必备)
《尼恩Java面试宝典》 40岁老架构师 尼恩 经过对大量 Java面试题 的不断梳理、迭代, 编著成5000页的《尼恩Java面试宝典》,致力于体系化, 系统化,形象化 梳理,形成一个大的知识体系,从而帮助大家 进大厂&a…...

线程池各个参数设置说明
1. corePoolSize 核心线程数 看处理业务属于IO密集型还是属于cpu密集型IO密集型: 通常设置为N1,还有一个计算公式:线程数 cpu数*(线程等待时间/线程总的处理时间) 但是由于服务器除了这个服务可能还部署有其他服务,…...

springBoot对接多个mq并且实现延迟队列---未完待续
mq调用流程 创建消息转换器 package com.wd.config;import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.context.annotation.Bean; import o…...

Pytorch从零开始实战04
Pytorch从零开始实战——猴痘病识别 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——猴痘病识别环境准备数据集模型选择模型训练数据可视化其他模型图片预测 环境准备 本文基于Jupyter notebook,使用Python3.8,Pytor…...

北大C++课后记录:文件读写的I/O流
前言 文件和平常用到的cin、cout流其实是一回事,可以将文件看作一个有限字符构成的顺序字符流,基于此,也可以像cin、cout读键盘数据那样对文件进行读写。 读写指针 输入流的read指针 输出流的write指针 注:这里的指针并不是普…...

详解Linux的grep命令
2023年9月19日,周二晚上 先写这么多吧,以后有空再更新,还要一些作业没写完.... 目录 概述查看grep命令的所有选项grep的常用选项选项-i选项-v选项-n选项-c编辑选项-l组合使用 概述 grep命令在Linux系统中是一个很重要的文本搜索工具和过…...

spark6. 如何设置spark 日志
spark yarn日志全解 一.前言二.开启日志聚合是什么样的2.1 开启日志聚合MapReduce history server2.2 如何开启Spark history server 三.不开启日志聚合是什么样的四.正确使用log4j.properties 一.前言 本文只讲解再yarn 模式下的日志配置。 二.开启日志聚合是什么样的 在ya…...