【原文】https://www.toutiao.com/i6566814959966093837/

Linux守护进程

一、 守护进程概述

守护进程,也就是通常所说的Daemon进程,是Linux中的后台服务进程。它是一个生存期较长的进程,通常独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。守护进程常常在系统启动时开始运行,在系统关闭时终止。

Linux系统有很多守护进程,大多数服务都是用守护进程实现的。例如常见的常见的守护进程包括系统日志进程syslogd、 web服务器httpd、邮件服务器sendmail和数据库服务器mysqld等。

二、进程与终端

在Linux中,每一个系统与用户进行交流的界面称为终端。从该终端开始运行的进程都会依附于这个终端,这个终端称为这些进程的控制终端。当控制终端被关闭时,相应的进程都会被自动关闭。

守护进程能够突破这种限制,它从开始运行,直到整个系统关闭才会退出。如果想让某个进程不会因为用户或终端的变化而受到影响,就必须把这个进程变成一个守护进程。

三、 查看守护进程

命令: ps axj

父进程ID : PPID

进程ID : PID

进程组ID : PGID

会话期ID : SID

终端ID : TTY

终端进程组ID : TPGID

状态 : STAT

用户 : UID

运行时间 : TIME

指令: COMMAND

四、 Linux守护进程编写(五步)

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

第一步完成以后,子进程就在形式上做到了与控制终端的脱离

由于父进程已经先于子进程退出,子进程变成孤儿进程

pid = fork();
if (pid > 0) /*父进程退出*/
{
exit(0);
}

由于守护进程是脱离控制终端的,因此,完成第一步后就会在shell终端里造成一程序已经运行完毕的假象。之后的所有后续工作都在子进程中完成,而用户在shell终端里则可以执行其他的命令,从而在形式上做到了与控制终端的脱离

由于父进程已经先于子进程退出,会造成子进程没有父进程,从而变成一个孤儿进程。在Linux中,每当系统发现一个孤儿进程,就会自动由1号进程收养。原先的子进程就会变成init进程的子进程。

2. 在子进程中创建新会话

setsid()函数作用

setsid函数用于创建一个新的会话,并使得当前进程成为新会话组的组长setsid函数能够使进程完全独立出来,从而脱离所有其他进程的控制。

进程属于一个进程组,进程组号(GID)就是进程组长的进程号(PID)。登录会话可以包含多个进程组。这些进程组共享一个控制终端。这个控制终端通常是创建进程的登录终端。控制终端,登录会话和进程组通常是从父进程继承下来的。我们的目的就是要摆脱它们,使之不受它们的影响。方法是在第1点的基础上,调用setsid()使进程成为会话组长。

进程组: 一个或多个进程的集合。进程组由进程组ID来唯一标识。每个进程组都有一个组长进程,进程组ID就是组长进程的进程号。

会话期: 会话组是一个或多个进程组的集合

进程组 对话期 终端

3. 修改当前工作目录

chdir(“/tmp”);

通常的做法是让“/”或”/tmp”作为守护进程的当前工作目录 。

在进程运行过程中,当前目录所在的文件系统是不能卸载的。

chdir函数可以改变进程当前工作目录

4. 重设置文件权限掩码

umask(0);

文件权限掩码是指文件权限中被屏蔽掉的对应位。把文件权限掩码设置为0,可以增加该守护进程的灵活性。设置文件权限掩码的函数umask();

5. 关闭文件描述符

fdtablesize = getdtablesize();

for (fd = 0; fd < fdtablesize; fd++)

close(fd);

新建的子进程会从父进程那里继承所有已经打开的文件。在创建完新的会话后,守护进程已经脱离任何控制终端,应当关闭用不到的文件。这些被打开的文件可能永远不会被守护进程读或写,但它们一样消耗系统资源,而且可能导致所在的文件系统无法卸载

从终端输入的字符不可能达到守护进程,守护进程中用常规的方法(如printf)输出的字符也不可能在终端上显示出来。所以,文件描述符为0、1和2的三个文件(对应标准输入、标准输出和标准错误这三个流)已经失去了存在的意义,也应被关闭。

五、 应用代码举例

创建一个守护进程每隔1s向daemon.txt文件中写入一次系统时间。

#include
int main()
{
pid_t pid;
int num,i;
int fd;
time_t t;
char buf[100];
pid = fork();
//第一步:创建子进程,父进程结束(子进程有init进程托管);
if(pid == 0){
//第二步:创建新会话,脱离原来的进程,脱离控制终端,脱离原来的进程组;
setsid();
//第三步:修改当前目录,每一个进程都有一个当前目录;(不是必须的)
chdir("/tmp");
//第四步:重新设置文件权限掩码(不是必须的)
umask(0);
//第五步:关闭打开的文件描述符(如果父进程打开的文件,子进程会继承过来)
num = getdtablesize(); //获得当前打开的文件描述符表
for(i = 0; i < num; i++){
close(i);
}
fd = open("daemon.txt",O_WRONLY | O_CREAT ,0666);
while(1){
t = time(0);
sprintf(buf,"time: %s ",ctime(&t));
write(fd,buf,strlen(buf));
sleep(1);
}
}else if(pid > 0){
exit(0);
}
return 0;
}

【转】学习Linux守护进程详细笔记的更多相关文章

  1. 笔记整理--Linux守护进程

    Linux多进程开发(三)进程创建之守护进程的学习 - _Liang_Happy_Life__Dream - 51CTO技术博客 - Google Chrome (2013/10/11 16:48:2 ...

  2. CentOS 7.4 初次手记:第一章 Linux守护进程(daemon)

    第一节 init & sysvinit 6 I sysvinit 运行顺序... 6 II Sysvinit和系统关闭... 7 III Sysvinit 的小结... 7 IV 运行级别.. ...

  3. Linux守护进程编写指南

    Linux守护进程编写指南 守护进程(Daemon)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程是一种很有用的进 程.Linux的大多数服务器 ...

  4. .NET跨平台实践:用C#开发Linux守护进程

    Linux守护进程(Daemon)是Linux的后台服务进程,它脱离了与控制终端的关联,直接由Linux init进程管理其生命周期,即使你关闭了控制台,daemon也能在后台正常工作. 一句话,为L ...

  5. .NET跨平台实践:用C#开发Linux守护进程(转)

    Linux守护进程(Daemon)是Linux的后台服务进程,它脱离了与控制终端的关联,直接由Linux init进程管理其生命周期,即使你关闭了控制台,daemon也能在后台正常工作. 一句话,为L ...

  6. [转]❲阮一峰❳Linux 守护进程的启动方法

    ❲阮一峰❳Linux 守护进程的启动方法 "守护进程"(daemon)就是一直在后台运行的进程(daemon). 本文介绍如何将一个 Web 应用,启动为守护进程. 一.问题的由来 ...

  7. Server Develop (七) Linux 守护进程

    守护进程 守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程常常在系统引导装 ...

  8. Linux 守护进程和超级守护进程(xinetd)

    一 .Linux守护进程 Linux 服务器在启动时需要启动很多系统服务,它们向本地和网络用户提供了Linux的系统功能接口,直接面向应用程序和用户.提供这些服务的程序是由运行在后台的守护进程来执行的 ...

  9. Linux守护进程详解(init.d和xinetd) [转]

    一 Linux守护进程 Linux 服务器在启动时需要启动很多系统服务,它们向本地和网络用户提供了Linux的系统功能接口,直接面向应用程序和用户.提供这些服务的程序是由运行在后台 的守护进程来执行的 ...

随机推荐

  1. HBase:分布式列式NoSQL数据库

    传统的ACID数据库,可扩展性上受到了巨大的挑战.而HBase这类系统,兼具可扩展性的同时,也提出了类SQL的接口. HBase架构组成 HBase采用Master/Slave架构搭建集群,它隶属于H ...

  2. MYSQL用户权限管理(Grant,Revoke)

    MySQL可以为不同的用户分配严格的.复杂的权限.这些操作大多都可以用SQL指令Grant(分配权限)和Revoke(回收权限)来实现. Grant可以把指定的权限分配给特定的用户,如果这个用户不存在 ...

  3. Deep learning with Python 学习笔记(1)

    深度学习基础 Python 的 Keras 库来学习手写数字分类,将手写数字的灰度图像(28 像素 ×28 像素)划分到 10 个类别 中(0~9) 神经网络的核心组件是层(layer),它是一种数据 ...

  4. webpack4使用mode优化开发环境配置

    @subject: webpack mode @author: leinov @date: 2018-11-29 mode webpack的 mode 配置用于提供模式配置选项告诉webpack相应地 ...

  5. 深入出不来nodejs源码-从fs.stat方法来看node架构

    node的源码分析还挺多的,不过像我这样愣头完全平铺源码做解析的貌似还没有,所以开个先例,从一个API来了解node的调用链. 首先上一张整体的图,网上翻到的,自己懒得画: 这里的层次结构十分的清晰, ...

  6. Spring学习之路-从入门到放弃

    后台框架是真难入门啊!!!IDE的使用,环境的搭建,框架下载,上手,每一步都恶心人. 花了整整两天,才学会用idea,并且初步了解了maven(TM就是一个npm),然后跟着下载了对应的jar包,搭建 ...

  7. js 筛选数据

    <input type="text" id="filterName"> <div class="scope fr"> ...

  8. Netty的基本概念

    异步 等待它的同时你也可以做点别的事情 阻塞I/O 只能同时处理一个连接,要管理多个并发客户端,需要为每个新的客户端Socket创建一个新的Thread 使用Selector的非阻塞I/O class ...

  9. 一起来看看JavaScript中==和===有何不同

    '; // => true 如果其中一个值是true,则将其转换为1再进行比较.如果其中一个值是false,则将其转换为0再进行比较: true == 0; // => false fal ...

  10. 排序算法(8)--Merge Sorting--归并排序--Merge sort--归并排序

    1.基本思想  归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列:即先使每个子序 ...