【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两次有什么区别 的相关文章

  • Web 应用程序的带宽和流量模拟器?

    您能否建议如何创建一个测试环境来模拟 Web 应用程序中的各种类型的带宽和流量 或者也许是一个针对本地主机执行此操作的开源程序 我认为在编写网络应用程序时这是一个非常重要的主题 但这不是一个常见的主题 我能想象创建这种环境的唯一方法是在本地
  • X11 模式对话框

    如何使用 Xlib 在 X11 中创建模式对话框 模态对话框是一个位于应用程序其他窗口之上的窗口 就像瞬态窗口一样 并且拒绝将焦点给予应用程序的其他窗口 在 Windows 中 当试图从模态窗口夺取焦点时 模态也会通过闪 烁模态窗口的标题栏
  • 配置:错误:无法运行C编译的程序

    我正在尝试使用 Debian Wheezy 操作系统在我的 Raspberry Pi 上安装不同的软件 当我运行尝试配置软件时 我尝试安装我得到此输出 checking for C compiler default output file
  • 推荐用于小型站点的 IRC 服务器 (ircd)? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 情况 我想使用 IRC 机器人作为我正在研究的其他代码的通用通信接口 服务器硬件陈旧且内存不足 但运行在相对最新的 Debian GNU
  • 找出 Linux 上的默认语言

    有没有办法从C语言中找出Linux系统的默认语言 有 POSIX API 可以实现这个功能吗 例如 我想要一个人类可读格式的字符串 即德语系统上的 German 或 Deutsch 法语系统上的 French 或 Francais 等 有类
  • 用于编辑 /etc/sudoers 文件的正则表达式模式

    我想删除 etc sudoers 文件中的 uncommnet 轮组 那么我应该使用什么正则表达式模式 cat etc sudoers Allows members of the sys group to run networking so
  • 如何在gnuplot中将字符串转换为数字

    有没有办法将表示数字 以科学格式 的字符串转换为 gnuplot 中的数字 IE stringnumber 1 0e0 number myconvert stringnumber plot 1 1 number 我可能使用 shell 命令
  • 未找到 Gem 命令

    我已经在 Ubuntu 10 10 32 位上安装了 gem apt get install gem y 但当我尝试跑步时 gem install something gem 我收到未找到命令的错误 bash gem command not
  • 在 Docker 容器中以主机用户身份运行

    在我的团队中 我们在进行开发时使用 Docker 容器在本地运行我们的网站应用程序 假设我正在开发 Flask 应用程序app py具有依赖关系requirements txt 工作流程大致如下 I am robin and I am in
  • C++:Linux平台上的线程同步场景

    我正在为 Linux 平台实现多线程 C 程序 其中我需要类似于 WaitForMultipleObjects 的功能 在搜索解决方案时 我发现有一些文章描述了如何在 Linux 中实现 WaitForMultipleObjects 功能
  • 无需 root 访问权限即可安装 zsh? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 有可能 以及如何 我确实需要在几台具有 ssh 访问权限 但没有 root 访问权限 的远程计算机上使用此功能 下载 zsh wget O zsh t
  • Python将文件从Linux复制到WIndows

    我正在构建一个网站 该网站有一个表单 可以捕获用户数据并在用户数据上运行一些cgi cgi 的第一步是需要将文件从 Linux Web 服务器复制到 Windows 计算机 服务器将使用 Active Directory 角色帐户作为复制凭
  • 使用c在linux上分块读写

    我有一个 ASCII 文件 其中每一行都包含一个可变长度的记录 例如 Record 1 15 characters Record 2 200 characters Record 3 500 characters Record n X cha
  • 如何列出 nginx 中的所有虚拟主机

    有没有一个命令可以列出 CentOS 上 nginx 下运行的所有虚拟主机或服务器 我想将结果通过管道传输到文本文件以用于报告目的 我正在寻找与我用于 Apache 的命令类似的命令 apachectl S 2 gt 1 grep 端口 8
  • 提高mysql导入速度[关闭]

    Closed 这个问题是与编程或软件开发无关 help closed questions 目前不接受答案 我有一个很大的数据库22GB 我曾经用过进行备份mysqldumpgzip 格式的命令 当我提取 gz 文件时 它会生成 sql文件的
  • 为什么默认情况下不启用 arp 忽略/通告 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我有一个需要经验才能回答的具体问题 为什么 arp ignore arp announce 在 Linux 安装 例如 debian 上默认不启用 有
  • 运行 shell 命令并将输出发送到文件?

    我需要能够通过 php 脚本修改我的 openvpn 身份验证文件 我已将我的 http 用户设置为免通 sudoer 因为这台机器仅在我的家庭网络中可用 我目前有以下命令 echo shell exec sudo echo usernam
  • pthread_self() 返回的线程 ID 与调用 gettid(2) 返回的内核线程 ID 不同

    这句话来自于pthread self 的手册页 http linux die net man 3 pthread self 那么 我应该根据什么来决定是否应该使用pthread self or gettid确定哪个线程正在运行该函数 两者都
  • 亚马逊 Linux - 安装 openjdk-debuginfo?

    我试图使用jstack在 ec2 实例上amazon linux 所以我安装了openjdk devel包裹 sudo yum install java 1 7 0 openjdk devel x86 64 但是 jstack 引发了异常j
  • 如何使用 VSCode 调试 Linux 核心转储?

    我故意从我使用 VSCode 编写的 C 应用程序生成核心转储 我不知道如何调试核心转储 有没有人愿意分享这方面的经验 更新 我相信我现在已经可以使用了 我为核心文件创建了第二个调试配置 我需要添加指向生成的转储文件的 coreDumpPa

随机推荐

  • 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下大多数服务器就是用守护进程实现的 因为它独立于终端运行 也就是说它的运行不受当前登录或者注销的影响 自成会话