Linux C语言 23-守护进程

Linux C语言 23-守护进程

本节关键字:守护进程、daemon
相关C库函数:sigset、signal、fork、setsid、chdir、umask、open、write、close、sleep

什么是守护进程?

  • 守护进程(Daemon)也被翻译为精灵进程、后台进程,守护进程的运行不受终端影响,可以长期稳定地运行服务,直到整个系统关闭才退出;
  • 守护进程是后台运行的、系统启动是就存在的、不予任何终端关联的,用于处理一些系统级别任务的特殊进程;
  • 若是想让某个进程不受用户、中断或其它变化的影响,那么必须把这个进程变成一个守护进程;

Unix/Linux系统中守护进程的查看

  • ps -ef | grep ‘.*d$’ 可以看到许多以-d结尾的进程,这些进程大多数都是守护进程;
  • ps -axj a表示列出所有用户的进程 x表示列出有终端和无终端的进程 j表示列出与作业控制相关的信息,这些信息中凡是TPGID一栏为-1的基本上都是守护进程。

守护进程的编写

守护进程的惯例

在unix系统中,守护进程的设计通常遵循以下原则:

  • 如果守护进程使用锁文件,则该锁文件通常位于/var/run目录中。然而需要注意的是,在该目录创建文件通常需要超级用户的权限,锁文件的名字通常是name.pid,例如cron守护进程锁文件的名字是/var/run/crond.pid;
  • 如果守护进程支持配置选项,那么该配置文件一般是放在/etc目录下,文件名字一般是name.conf,name是该守护进程或服务的名字,例如mysqld配置文件的名字是/etc/my.cnf;
  • 守护进程可以使用命令启动,但是该启动命令一般在系统初始化的脚本中进行。如果守护进程终止,应当自动进行重启;如果一个守护进程更新了配置文件,则应该重新启动;
  • 为了避免每次更改配置文件都需要重启进程的问题,某些进程将捕捉SIGHUP信号,接收到此信号时自动重新读取配置文件。
守护进程的编写步骤

(1)创建子进程,父进程退出(使子进程称为孤儿进程,此时init进程会将孤儿进程收录);
这是编写守护进程的第一步,因为守护进程是脱离终端的,所以完成第一步后就会在shell终端里形成一个程序已经运行完毕的假象。以后的全部工做在子进程中完成,而用户在shell终端里则能够执行其余命令,从而在形式上作到了与控制终端脱离。
(2)在子进程中建立新的会话(脱离控制终端);
在子进程中建立新的会话(脱离控制终端):这步是建立守护进程中最重要的一步,虽然实现起来很简单,可是它的意义很是重要,在这里使用的是系统函数setsid()来建立一个新的会话,而且担任该会话组的组长。
(3)更改当前工作目录;
使用fork()建立的子进程是继承了父进程的当前工做目录,因为在进程运行中,当前目录所在的文件系统是不能卸载的,这对之后使用会形成不少的麻烦。所以一般的作法是让“/”做为守护进程的当前目录,固然也能够指定其余的别的目录来做为守护进程的工做目录。
(4)重设文件权限掩码;
文件权限掩码是屏蔽掉文件权限中的对应位。因为使用fork()函数新建立的子进程继承了父进程的文件权限掩码,这就给该子进程使用文件带了不少的麻烦(好比父进程中的文件没有执行文件的权限,然而在子进程中但愿执行相应的文件这个时候就会出问题)。所以在子进程中要把文件的权限掩码设置成为0,即此时有最大的权限,这样能够大大加强该守护进程的灵活性。设置的方法是:umask(0)。
(5)关闭文件描述符;
同文件权限码同样,用fork()函数新建的子进程会从父进程那里继承一些已经打开了的文件。这些文件被打开的文件可能永远不会被守护进程读写,若是不进行关闭的话将会浪费系统的资源,形成进程所在的文件系统没法卸下以及引发预料的错误。
(6)守护进程的退出,如果程序内部不做任何处理,则需要使用kill命令来终止守护进程,因此建议在守护进程中使用signal信号处理来实现进程的正常退出。

补充说明:

  • 进程组(process group):一个或多个进程的集合,每个进程组有惟一一个进程组ID,即进程组长进程的ID。
  • 会话期(session):一个或多个进程组的集合,有惟一一个会话期首进程(session leader)。会话期ID为首进程的ID。会话期能够有一个单独的控制终端(controlling terminal)。与控制终端链接的会话期首进程叫作控制进程(controlling process)。当前与终端交互的进程称为前台进程组。其他进程组称为后台进程组。
  • 挂断信号(SIGHUP):默认的动做是终止程序。当终端接口检测到网络链接断开,将挂断信号发送给控制进程(会话期首进程)。若是会话期首进程终止,则该信号发送到该会话期前台进程组。一个进程退出致使一个孤儿进程组中产生时,若是任意一个孤儿进程组进程处于STOP状态,发送SIGHUP和SIGCONT信号到该进程组中全部进程。所以当网络断开或终端窗口关闭后,控制进程收到SIGHUP信号退出,会致使该会话期内其余进程退出。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/ioctl.h>#define MAXFILE 65535int main(void)
{pid_t pid;int i, fd, len;char *buf = "this is my dameon\n";len = strlen(buf);#ifdef SIGTTOU // (可选)sigset(SIGTTOU, SIG_IGN); // 忽略写终端信号sigset(SIGTTIN, SIG_IGN); // 忽略读终端信号sigset(SIGTSTP, SIG_IGN); // 忽略Ctrl+Z信号
#endif// 1、创建子进程 并结束父进程pid = fork(); if (pid < 0){printf("error fork \n");exit(1);}else if (pid > 0){exit(0);    // 结束父进程}// 2、在子进程中建立新的会话 // 调用setsid函数的进程成为新会话的领头进程,并脱离其父进程的会话组和进程组// 由于会话对控制终端的独占性,子进程同时与控制终端脱离setsid();if ((fd=open("/dev/tty", O_RDWR)) >= 0){// 解除进程与当前控制台的联系ioctl(fd, TIOCNOTTY, (char*)NULL);close(fd);}if (fork() > 0){// fork第二次主要目的是。防止进程再次打开一个控制终端// 可以省略此步,因为打开一个控制终端的前台条件是该进程必须是会话组长。再fork一次,子进程ID != sid(sid是进程父进程的sid)。因此也没法打开新的控制终端exit(0);}// 3、更改当前的工作目录 摆脱父进程的影响chdir("/");// 4、重新文件权限掩码umask(0);// 5、关闭文件描述符(有些操作系统可不关闭)for (i=0; i<MAXFILE; i++){// 关闭文件描述符(常说的输入,输出,报错3个文件),// 由于守护进程要失去了对所属的控制终端的联系,这三个文件要关闭close(i);}while (1){// 测试程序,每10秒向指定文件中写入一次内容if ((fd=open("/tmp/mydameontest.txt", O_CREAT|O_WRONLY|O_APPEND, 0600)) < 0){printf("open file err \n");exit(0);}write(fd, buf, len+1);close(fd);sleep(10);}
}
/** 运行结果:
运行程序后,执行命令 tail -f /tmp/mydaemontest.txt
# tail -f mydaemontest.txt 
this is my daemon
this is my daemon
this is my daemon
this is my daemon*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/179457.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux编写Shell命令脚本

1.编写Shell脚本 可以将Shell终端解释器当作人与计算机硬件之间的“翻译官”&#xff0c;它作为用户与Linux系统内部的通信媒介&#xff0c;除了能够支持各种变量与参数外&#xff0c;还提供了诸如循环、分支等高级编程语言才有的控制结构特性。要想正确使用Shell中的这些功能…

git的创建以及使用

1、上传本地仓库 首先确定项目根目录中没有.git文件&#xff0c;有的话就删了&#xff0c;没有就下一步。在终端中输入git init命令。注意必须是根目录&#xff01; 将代码存到暂存区 将代码保存到本地仓库 2、创建git仓库 仓库名称和路径&#xff08;name&#xff09;随便写…

vscode 里怎么自动提示 webpack 配置项?

webpack 的配置项非常多&#xff0c;容易忘记&#xff0c;能自动提示很有用&#xff0c;就是在配置文件里面添加下面代码 // 下面这行用于 vscode 中智能化自动提示 webpack 配置项 /** type {import(webpack).Configuration} */

力扣二叉树--第三十二天

前言 关于路径的两道题。掌握递归函数要不要返回值。用到了defer关键字&#xff0c;起到回溯的作用。 内容 一、路经总和 112.路径总和 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所…

文本三剑客之sed

一、sed编辑器 ■ sed是一种流编辑器&#xff0c;流编辑器会在编辑器处理数据之前基于预先提供的—组规则来编辑数据流 ■ sed编辑器可以根据命令来处理数据流中的数据&#xff0c;这些命令要么从命令行中输入&#xff0c;要么存储在一个命令文本文件中 1、sed的工作流程主要…

分享一个适用于 Vue3 的好的组件库,PrimeVue组件。

一、PrimeVue介绍 PrimeVue 是一个基于 Vue.js 的 UI 组件库&#xff0c;专注于提供丰富、灵活、现代的 UI 组件&#xff0c;以帮助开发者构建功能强大的 Web 应用程序。PrimeVue 提供了一系列的组件&#xff0c;涵盖了从基本的表单元素到高级的数据表格和图表等各种组件。 二、…

大模型fine-tune 微调

大模型的 Fine-tune 我们对技术的理解&#xff0c;要比技术本身更加重要。 正如我在《大模型时代的应用创新范式》一文中所说&#xff0c;大模型会成为AI时代的一项基础设施。 作为像水、电一样的基础设施&#xff0c;预训练大模型这样的艰巨任务&#xff0c;只会有少数技术…

测试用例设计全网最强篇(建议收藏)

本篇从多角度带大家从0开始学习怎么写测试用例&#xff0c;七种方法8个案例&#xff08;含用例模板&#xff09;&#xff1b;学习目标&#xff1a;测试用例的基本知识以及黑盒测试用例的设计方法。 前言&#xff1a;总体编写策略&#xff1a; 对于测试用例编写来说&#xff0…

只会在终端使用Python运行代码?这些高级用法了解了解

大部分同学在终端使用Python可能只是简单的执行代码&#xff0c;但其实结合一些Python内置模块或第三方库可以实现更高级且便捷的用法&#xff0c;一起看看吧 插播&#xff0c;更多文字总结指南实用工具科技前沿动态第一时间更新在公粽号【啥都会一点的研究生】 代码Benchmar…

CG向量和矩阵元素的获取

swizzle swizzle可以获取向量分量值&#xff1b;表现形式是点符号和rgba或xyzw rgba一般用作颜色表示 xyzw一般用于坐标表示分量值可以进行组合 例如&#xff1a;fixed4 test(1,2,3,4) 获取分量值&#xff1a;test.r 获取第一个分量值、test.g、test.xy、test.yx 向量维度转换…

Java研学-IO流(一)

一 文件与流—真正存储数据的载体 1 存储关系与类型 文件 – 可以直接操作的数据资源载体 文件夹 – 同时存放一个或多个文件的"容器" 文本文件 – 纯文本:操作的是字符型数据:例如 .java/.txt/.class… 媒体文件 – 既可以包含文本也可以包含其他数据:操作字节…

香港科技大学数据建模(MSc DDM)硕士学位项目(2024年秋季入学)招生宣讲会-武汉专场

时间&#xff1a;2023 年12 月 8 日&#xff08;周五&#xff09; 15:00 地点&#xff1a;华中科技大学大学生活动中心B座303 嘉宾教授&#xff1a;张锐 教授 项目旨在培养科学或工程背景的学员从数据中提取信息的数据建模能力&#xff0c;训练其拥有优秀的解难和逻辑思考与分…

第一百八十三回 如何给图片添加阴影

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 实现方法 3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了"自定义可以滑动的刻度尺"样相关的内容&#xff0c;本章回中将介绍" 如何给图片添加阴影".闲话休提&#xff0c;让…

Windows环境下的JDK安装与环境配置

一、JDK下载 1、打开Oracle官方网站下载页 Java Downloads | Oracle 中国 2、选择Java archive页&#xff0c;在版本列表中选择需要下载的版本 3、选择系统环境对应的版本&#xff0c;点击对应的下载按钮&#xff0c;弹出技术许可勾选框 4、勾选Oracle技术许可协议 5、输入Or…

人工智能即将彻底改变你使用计算机的方式

文章目录 每个人的私人助理“Clippy 是一个机器人&#xff0c;而不是特工。”卫生保健“一半需要心理健康护理的美国退伍军人没有得到治疗。”教育生产率娱乐和购物科技行业的冲击波技术挑战隐私和其他重大问题 今天我仍然像保罗艾伦和我创办微软时一样热爱软件。但是&#xff…

项目监控:项目跟踪和控制的工具和步骤

项目管理不仅仅是分配和审查任务&#xff0c;还包括平衡团队成员的工作量、创建预测和避免障碍的工作流程。整个过程涉及许多步骤&#xff0c;因此&#xff0c;项目监控成为了成功业务活动的关键之一&#xff0c;是项目经理确保与团队共同实施的计划顺利进行的方式。 项目监控为…

算法基础课 (一) 基础算法

进制转换 #include<iostream> using namespace std; const int N 100; int n,m; string s; int x;//记录n进制转化成十进制; int ans[N]; int main(){cin>>n>>s>>m;int t1;for(int is.size()-1;i>0;i--){if(s[i]<A){x t*(int)(s[i]-0);t * n;…

c语言和c++的const的区别

const C中的const&#xff1a; 1.const修饰的局部变量赋值常量时&#xff0c;局部变量保存在符号表中&#xff0c;修改不了&#xff0c;是一个常量 2.const修饰的全局变量保存在常量区&#xff0c;不能被修改 3.const修饰的全局变量默认是内部链接属性&#xff0c;加上extern就…

案例-某乎参数x-zse-96逆向补环境

文章目录 前言一、流程分析二、导出代码三、补环境总结 前言 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则…

springboot实现验证码功能

转载自 : www.javaman.cn 1、编写工具类生成4位随机数 该工具类主要生成从0-9&#xff0c;a-z&#xff0c;A-Z范围内产生的4位随机数 /*** 产生4位随机字符串*/public static String getCheckCode() {String base "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn…