【Linux】如何创建daemon进程&fork一次和fork两次有什么区别

2023-11-01

前言


本文适合对Linux进程有了解过的读者。Linux中有一种进程叫做守护进程,又称精灵进程。它运行在后台,很重要,Linux下大多数服务器就是用守护进程实现的。因为它独立于终端运行,也就是说它的运行不受当前登录或者注销的影响,自成会话,周期性的执行某项任务或者等待处理某些事件。其他进程则是在登录或者运行时创建,在运行结束或者注销用户时终止。守护进程命名通常以d结尾,父进程是1号进程,它其实是属于孤儿进程,因为我们知道1号进程会领养所有无父进程的孤儿进程。

创建守护进程


创建守护进程可以分为如下几步:
1. umask设置为0。
2. 调用fork函数,再将父进程退出。
3. 调用setsid函数创建⼀个新的Session,并成为Session Leader。
4. 改变当前目录为根目录
5. 关闭文件描述符
6. 忽略SIGCHLD信号(子进程退出时会发给父进程的信号)

调用setsid函数之前,当前进程不允许是进程组的Leader,否则该函数返回-1。这就是fork后将父进程退出的原因。毕竟刚创建出来的子进程不会是进程组组长。

setsid函数的作用:
1)子进程成为新会话的⾸进程。
2)子进程成为⼀个进程组的组长进程 。
3)子进程没有控制终端。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<signal.h>
int main()
{
    umask(0);
    if(fork()>0)
    {
        exit(0);    //父进程退出
    }
    setsid();     //设置新会话
    chdir("/");   //更改当前工作目录为根目录
    close(0);    //关闭标准输入流
    close(1);     //关闭标准输出流
    close(2);    //关闭标准错误流
    signal(SIGCHLD,SIG_IGN);   //忽略SIGCHLD信号
    while(1)
    {
        sleep(1);
    }
    return 0;
}

可以看到,上面的代码中fork了一次就完成了对守护进程的创建。那为什么有人创建时需要fork两次呢?一次和两次的作用是不同的,如下:
调用第一次fork的作用
让shell认为这条命令已经终止,不用挂在终端输入上;为后面setsid服务,因为调用setsid函数的进程不能是进程组组长,如果不fork出子进程,则此时的父进程是进程组组长,就无法调用setsid。当子进程调用完setsid函数之后,子进程是会话组长也是进程组组长,并且脱离了控制终端,此时,不管控制终端如何操作,新的进程都不会收到一些信号使得进程退出。
第二次fork的作用
虽然当前关闭了和终端的联系,但是后期可能会误操作打开了终端。
但是只有会话首进程能打开终端设备,所以再fork一次,把父进程退出,再次fork的子进程作为守护进程继续运行,保证了该精灵进程不是对话期的首进程,第二次不是必须的,是可选的。

总结


守护进程是Linux中重要的角色,它无控制终端,自成会话,生存周期与用户登录注销无关,常用于常驻内存的网络服务。Linux提供了一个函数可以直接创建守护进程。

int daemon(int nochdir, int noclose);

使用时两个参数都传0即可,代表当前工作目录变更为根目录;关闭文件描述符。相当于文件描述符重定向到 /dev/null,写入到这里的内容会被操作系统丢弃。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Linux】如何创建daemon进程&fork一次和fork两次有什么区别 的相关文章

随机推荐

  • LVS+Keepalived群集

    LVS Keepalived群集 一 Keepalived实现原理 1 原理 2 Keepalived体系主要模块及其作用 3 Keepalived工具介绍 4 合格的集群应该具备的特性 二 Keepalived的部署 三 LVS Keep
  • IDEA插件

    Statistic 统计项目代码行数
  • python -m SimpleHTTPServer 使用详解

    我们可以很简单的使用 python m SimpleHTTPServer 快速搭建一个http服务 提供一个文件浏览的web服务 在linux系统上安装了Python后 Python自带了一个WEB服务器 SimpleHTTPServer
  • 艾宾浩斯30天计划表_利用艾宾浩斯遗忘曲线来复习

    学习路上 你我相伴 十年苦读 一朝决胜 记忆力是我们学习能力中十分重要的一种能力 无论是学习 工作 生活中处处都能用到 我们每个人都希望自己能够记忆力超群 过目不忘 但现实是 今天记忆的内容如果不及时复习 很快就会忘掉 今天小英就为大家介绍
  • mysql 把select结果保存为临时表,mysql中把查询结果输出到临时表

    mysql 把select结果保存为临时表 有2种方法 第一种 建立正式的表 此表可供你反复查询 drop table if exists a temp create table a temp as select 表字段名称 from 表名
  • 微信小程序直播插件live-player-plugin使用

    1 在你的小程序中 app json这个文件中引入直播组件 plugins live player plugin version 1 1 1 注意填写该直播组件最新版本号 微信开发者工具调试时可获取最新版本号 复制时请去掉注释 provid
  • IP地址与DNS之间的关系——真正理解DNS

    1 IP地址 容易理解而又不太准确的说 IP地址是电脑在网络中的唯一标识 局域网IP是限于局域网内可以相互访问的电脑 公网中的固定IP 可以说是电脑在公网网络中的唯一标识 2 DNS Domain Name System 域名服务系统 简单
  • qt当通过子进程的方式嵌入窗口后,键盘按键响应不了怎么办?

    案例问题 当通过QProcess类 创建了一个子线程后 再将该子线程中的窗口封装到QWidget后嵌入当前主窗口中后 当在操作主进程窗口后 再去操作子进程窗口时 这时出现子进程窗口无法获取到键盘消息 或者先操作子进程中的窗口后 再切换到主进
  • linux重启nginx脚本

    Nginx 启动 重启 停止脚本 第一步 先运行命令关闭nginx ps ef grep nginx 查看状态 sudo kill 9 进程号 第二步 sudo vi etc init d nginx 输入以下内容 bin bash ngi
  • Qt的信号与槽

    依旧是根据 C GUI QT4 这本书继续学习 槽函数是普通C 成员函数几乎是一样的 可以为虚函数 可以被重载 可以为公有 可以为私有 也可以被其他C 成员函数直接调用 同时 他们的参数可以为任意类型 唯一不同的是 槽函数可以和信号连接在一
  • Unable to cast object of type 'System.Object[]' to type 'Employee[]'

    错误 Unable to cast object of type System Object to type Employee public class Employee public int id public string firstN
  • spring boot 使用spring-boot-starter-mail发送邮件

    1 引入依赖
  • 小窗帘

    anjiula 给你的小情书 就像起风了 扯着飘飘摇摇的衣角 拉长简简单单的街道 轻轻浅浅的步伐 那时公交站台的星光 裹挟着被吹散的温度 一边冷 一边暖 还有我们傻傻的脑袋 思绪穿透黑夜里的 小窗帘 挡不住光线 也挡不住念想
  • MPC5643L单片机——CAN通信FIFO接收使用笔记

    一 一个FIFO最多可存储几组CAN数据 手册里介绍了RX FIFO的寄存器数据结构 0x90 0xDC保留用作存储FIFO引擎 它里面的结构和上面0x80 0x90完全一样吗 也是16个字节吗 好像没有说明 根据大小计算0xDC 0x90
  • MS Learn 宝藏资源库 - 学习经验分享

    点击蓝字 关注我们 作者 刘轶民 大家好 我是东北电力大学的一名在校学生 我叫刘轶民 很高兴能以 MS Learn 的受益者的身份 来分享一些经验与看法 作为正在上学的我来讲 很多时候我可能更多的去面临着新技术的学习而不是基于一套熟悉的框架
  • 如何快速爬取国内985大学学术学报pdf文件

    背景 最近 在爬取关于国内985大学的学报时 我注意到大部分大学学报站点格式都采用相似的形式 并且PDF链接都使用自增的ID 然而 我也发现了一个问题 即大多数PDF链接的ID并不是连续的 现在我将向你分享一些方法 以快速获取所有的大学学报
  • MATLAB二维绘图(二)向图中添加标题,坐标轴,图标和文字信息

    MATLAB二维绘图 二 向图中添加标题 坐标轴 图标和文字信息 1 添加标题 图例 x轴信息和y轴信息 示例 添加标题 clear clc close all x 0 0 1 2 pi y1 sin x y2 exp x plot x y
  • BUUCTF Misc杂项前十二道题的思路和感悟

    title BUUCTF Misc date 2021年8月18日 17点27分 tags MISC categories MISC 1 BUUCTF 签到题 直接告诉了flag 2 BUUCTF 第二道题 Stegsolve 下载附件之后
  • gdb

    gdb一般命令 1 gdb l 从第一行开始例出原码 2 gdb break 1 设置断点 在源程序第1行处 3 gdb info break 查看断点信息 4 gdb r 运行程序 run命令简写 5 gdb n 单条语句执行 next命
  • 【Linux】如何创建daemon进程&fork一次和fork两次有什么区别

    前言 本文适合对Linux进程有了解过的读者 Linux中有一种进程叫做守护进程 又称精灵进程 它运行在后台 很重要 Linux下大多数服务器就是用守护进程实现的 因为它独立于终端运行 也就是说它的运行不受当前登录或者注销的影响 自成会话