当前位置: 首页 > news >正文

使用香橙派学习 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&#xff1a;什么是守护进程 A&#xff1a;Linux Daemon&#xff08;守护进程&#xff09;是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行 某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务&#xff0c;不是对整个系统就是对某个…...

数据治理-数据仓库和商务智能

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

CH2--x86系统架构概览

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

Immutable.js API 简介

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

HLSL 入门(一)

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

【Docker】挂载数据卷

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

[技术干货]spring 和spring boot区别

Spring 和 Spring Boot 都是 Java 框架&#xff0c;用于构建企业级应用程序。Spring 是一个完整的框架&#xff0c;提供各种功能&#xff0c;包括依赖注入、事务管理、数据访问、Web 开发等。Spring Boot 是一个基于 Spring 的框架&#xff0c;旨在简化 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系统中的超级管理员用户帐户&#xff0c;该帐户拥有整个系统的最高权利&#xff0c;可以执行几乎所有操作。ROOT就是获取安卓系统中的最高用户权限&#xff0c;以便执行一些需要高权限才能执行的操作(包括卸载系统自带程序、刷机、备份、还原…...

【云原生】k8s-----集群调度

目录 1.k8s的list-watch机制 1.1 list-watc机制简介 1.2 根据list-watch机制&#xff0c;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

作业&#xff1a; 1> 将之前定义的栈类和队列类都实现成模板类 栈&#xff1a; #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转建表语句

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

封装使用Axios进行前后端交互

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

SOA、分布式、微服务

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

json数据传输压缩以及数据切片分割分块传输多种实现方法,大数据量情况下zlib压缩以及bytes指定长度分割

json数据传输压缩以及数据切片分割分块传输多种实现方法&#xff0c;大数据量情况下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测试-如何指定测试策略、测试标准?

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

【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…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...