【原文】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. T-SQL 分布式查询

    --返回本地服务器中定义的链接服务器列表. EXEC sys.sp_linkedservers /* 创建或更新 SQL Server 本地实例上的登录名与远程服务器中安全帐户之间的映射. 当用户登录 ...

  2. css3 2D转换(2D Transform) 动画(Animation)

    transform 版本:CSS3 内核类型 写法 Webkit(Chrome/Safari) -webkit-transform Gecko(Firefox) -moz-transform Pres ...

  3. windows开机提示文件损坏

    今早按部就班的开机,然后准备吃热干面,很多时候事情都是同步进行的... 然后眼前出现这样一个界面 心情果断灰暗下来,按照提示一步步操作,点enter进入高级选项,试过了安全模式启动.最后一次正确配置启 ...

  4. Netty 高性能之道 FastThreadLocal 源码分析(快且安全)

    前言 Netty 作为高性能框架,对 JDK 中的很多类都进行了封装了和优化,例如 Thread 类,Netty 使用了 FastThreadLocalRunnable 对所有 DefaultThre ...

  5. 深入出不来nodejs源码-内置模块引入初探

    重新审视了一下上一篇的内容,配合源码发现有些地方说的不太对,或者不太严谨. 主要是关于内置模块引入的问题,当时我是这样描述的: 需要关注的只要那个RegisterBuiltinModules方法,从名 ...

  6. [转]Easily Add a Ribbon into a WinForms Application

    本文转自:https://www.codeproject.com/articles/364272/easily-add-a-ribbon-into-a-winforms-application-cs ...

  7. ASP.NET开发,从二层至三层,至面向对象 (5)

    此是一系列博文,最后一篇了.也是面向初学者而作,望你们能有更好,更多对ASP.NET面向对编程了解与认识. 前一篇中<ASP.NET开发,从二层至三层,至面向对象 (4)>http://w ...

  8. VC++窗口创建过程,图形绘制,时钟程序

    创建窗口步骤: (1)注册窗口类(RegisterClassEx) (2)创建窗口(CreateWindowEx) (3)在桌面显示窗口(ShowWindow) (4)更新窗口客户区(UpdateWi ...

  9. C# 导出Excel表格

    function exportExcel() { //查询条件 var startTime = F.ui.startTime.getText() == "" ? null : F. ...

  10. c# 控制台应用程序批量修改文件夹下的后缀名(包括子文件夹)

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Tex ...