1.1 认识守护进程
1、守护进程也称为精灵进程(daemon),是运行在后台的一种特殊进程。它独立于控制终端并且周期性的执行某种任务或等待某些发生的事件。守护进程是一种很有用的进程。Linux的大多数服务器就是用守护进程实现的。比如:ftp服务器,ssh服务器,web服务器httpd等。同时,守护进程完成许多系统任务。比如,作业规划进程crond等。
2、Linux系统启动时会启动很多系统服务进程,这些系统服务进程没有控制终端,不能直接和用户交互。其他进程都是在用户登录或运行程序时创建,在运行结束或用户注销时终止,但是系统服务进程(守护进程)不受用户登录和注销的影响,它们一直运行着。这种进程有一个名称叫守护进程(daemon)。
3、用ps -axj命令查看系统中的进程。参数a表示不仅列当前用户的进程,也列出所有其他用户的进程;参数x表示不仅列出有控制终端的进程,也列出所有无控制终端的进程;参数j表示列出与作业控制相关的进程。

解释:
(1)凡是TPGID一栏写着-1的都是没有控制终端的进程,也就是守护进程。
(2)在COMMAND一列用[]括起来的名字表示内核线程,这些线程在内核里创建,没有用户控件代码,因此没有程序文件名和命令行,通常采用以k开头的名字,表示Kernel。
(3)init进程是所有文件的父进程,udevd负责维护/dev目录下的设备文件,acpid负责电源管理syslogd负责维护/var/log下的日志文件。
(4)守护进程采用以d结尾的名字,表示daemon。
2.1 创建守护进程
创建守护进程最关键的一步是调用setsid函数创建一个新的session,并且成为session leader。
2.1.1 setsid语法

#include<unistd.h>
pid_t setsid(void);

注意:
(1)该函数调用成功时返回新创建session的id(其实就是当前进程的id),出错返回-1。
(2)调用这个函数之前,当前进程不允许是进程组的leader,否则该函数返回-1。
(3)要保证当前进程不是进程组的leader也很容易,只要先fork再调用setsid就行了。fork创建的子进程和父进程在同一个进程组中,进程组的leader必然是该组的第一个进程,所以子进程不可能是该组的第一个进程,在子进程中调用setsid就不会出现问题了。
2.1.2 成功调用函数的结果
(1)创建一个新的session,当前进程成为session leader,当前进程id就是session的id。
(2)创建一个新的进程组,当前进程成为进程组的leader,当前进程的id就是进程组的id。
(3)如果当前进程原本有一个控制终端,则它失去这个控制终端,成为一个没有控制终端的进程。所谓失去控制终端是指原来的控制终端仍然是打开的,仍然可以读写,但只是一个普通的打开文件而不是控制终端了。
3.1 守护进程代码

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<signal.h>
#include<fcntl.h>
#include<sys/stat.h>void mydaemon(void)
{int i;int fd0;pid_t pid;struct sigaction sa;umask(0);pid = fork();if(pid < 0){perror("fork error!\n");exit(1);}else if(pid > 0){exit(0);}setsid(); //创建一个会话sa.sa_handler = SIG_IGN;sa.sa_flags = 0;sigemptyset(&sa.sa_mask);if(sigaction(SIGCHLD, &sa, NULL) < 0){//注册子进程退出忽略信号return ;}if(chdir("/") < 0){//将当前工作目录更改为根目录printf("chlid dir error!\n");return;}//关闭不需要的文件描述符,或者重定向到/dev/nullclose(0);fd0 = open("/dev/null", O_RDWR);dup2(fd0, 1);dup2(fd0, 2);
}int main()
{mydaemon();while(1){sleep(1);}
}

运行结果:

释:
(1)chdir:更改当前目录或文件夹。头文件:#include<unistd.h>。定义函数:int chdir(const char* path)。返回值:成功返回0,失败返回-1。
(2)daemon:用于创建守护进程。头文件:#include<unistd.h>。定义函数:int daemon(int nochdir, int noclose)。返回值:成功返回0,失败返回-1。其中,当nochdir为0时,daemon将更改当前目录为根目录“/”;当noclose为0时,daemon将进程的STDIN、STDOUT和STDERR重定向为/dev/null。
(3)dup:复制文件句柄。头文件:#include<unistd.h>;。定义函数:int dup(int fd)。返回值:成功返回新的文件描述符;失败返回-1。
(4)dup2:复制文件句柄。头文件:#include<unistd.h>。定义函数:int dup2(int oldhandle, int newhandle)。返回值:成功返回新的文件描述符;失败返回-1。
(5)sigaction:查询或设置信号处理方式。头文件:#include<signal.h>。定义函数:int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)。返回值:成功返回0;失败返回-1。该函数会依参数signum指定的信号编号设置信号的处理函数,参数signum可以指定SIGKILL和SIGSTOP以外的所有信号。act信号处理函数参数采用指针函数的方式,参数有:
1)sa_handle:与signal的参数handle相同,代表新的信号处理函数;
2)sa_mask:设置在处理该信号时暂时将sa_mask指定的信号集搁置;
3)sa_flags:用来设置信号处理的其他相关操作。

Linux 守护进程相关推荐

  1. Linux守护进程实现

    Linux守护进程 redis版: void daemonize(void) {int fd;if (fork() != 0) exit(0); /* parent exits */setsid(); ...

  2. Linux 命令详解(六)Linux 守护进程的启动方法

    Linux 守护进程的启动方法 http://www.ruanyifeng.com/blog/2016/02/linux-daemon.html

  3. .NET跨平台实践:.NetCore、.Net5/6 Linux守护进程设计

    几年前,我写过两篇关于用C#开发Linux守护进程的技术文章,分别是<.NET跨平台实践:用C#开发Linux守护进程.NET跨平台实践:再谈用C#开发Linux守护进程 - 完整篇 这就是本文 ...

  4. .NET跨平台实践:再谈用C#开发Linux守护进程 — 完整篇

    Linux守护进程是Linux的后台服务进程,相当于Windows服务,对于为Linux开发服务程序的朋友来说,Linux守护进程相关技术是必不可少的,因为这个技术不仅仅是为了开发守护进程,还可以拓展 ...

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

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

  6. 深入理解Linux守护进程

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

  7. Linux守护进程的创建(结合nginx框架)

    Linux守护进程的创建(结合nginx框架) 先介绍几个相关函数: int dup2(arg1,arg2):参数一指向的内容赋给参数二,shi的参数二也能访问参数一所指向的内容,并返回新的描述符 i ...

  8. linux+守护进程+php,【转载】Linux 守护进程的编程方法

    [转载]Linux 守护进程的编程方法 原文见: http://www.linuxdevelop.org/tingxx/show.php?table=c&id=3 Linux 守护进程的编程方 ...

  9. linux 守护进程_网络工程师之linux守护进程

    Linux守护进程就是通常所说的DEAMON进程,linux后台服务多种多样,每一个服务都运行一个对应的程序,这些后台程序对应的进程就是守护进程.系统中可以看到很多如DHCPD和HTTPD之类的进程, ...

  10. 【Linux】Linux 守护进程的启动方法

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

最新文章

  1. Java是如何实现自己的SPI机制的? JDK源码(一)
  2. 嵌入式中断服务函数的一些特点
  3. 整合Struts2、Spring、Hibernate构建J2EE应用
  4. mysql 使用场景_MySQLMHA典型使用场景
  5. 全数字实时仿真平台SkyEye的同步数据流语言可信编译器的构造
  6. 《Python程序设计》——1.2 程序开发周期
  7. 开源项目贡献者_扩大项目贡献者基础的5种方法
  8. dubbo快速实战(非最佳配置,演示用)
  9. QT分析之网络编程(七)
  10. Java开发笔记(一百三十二)Swing的表格
  11. python scipy版本_Py之Scipy:Python库之Scipy库的简介、安装、使用方法详细攻略
  12. java同步锁-详细易懂
  13. Transmission下载安装
  14. 企业微信可以同步微信好友吗?怎么同步?
  15. 使用 snapseed p 图,图片局部黑白,简单实用!!
  16. 7-3 敲笨钟 (20 分)Java
  17. 微信小程序学习笔记③——wxml+wxss+js基础入门[样例+解析]
  18. 第三方网站不能调用微信公众平台里的图片了 显示此图片来自微信公众号平台未经允许不可引用...
  19. 数数小绵羊(C++)
  20. python 重试—retry库的使用和自定义超时retry

热门文章

  1. 年薪20-50万 | 艾视维科技“3D视觉算法工程师”岗位招人啦!
  2. 糊糊作品--主题模板神偷
  3. 【EPLAN 公网部件库搭建与使用】
  4. 客户机 服务器系统的特点是客户机和服务器,客户机 服务器数据库系统的特点...
  5. 计算机类投稿心得(转
  6. UR机械臂学习(5-1):驱动真实机械臂准备工作——示教器配置
  7. DolphinScheduler任务类型梳理
  8. ICMP与DHCP(包含DHCP的全局配置模式与接口配置模式)
  9. 女孩子起名大全:知书达理的女孩名字,不动心都不行
  10. 中国阻焊油墨市场深度研究分析报告