什么是守护进程?

在了解守护进程之前,需要先知道什么是什么是终端?什么是作业?什么是进程组?什么是会话?

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

守护进程就是一个生存周期较长,独立于控制终端并且周期性执行某种任务的进程。 之所以要脱离终端,就是为了防止进程运行过程中被任何终端信息所打断

所以,要创建守护进程,我们就要将这个进程脱离终端。

shell分前后台作业来控制的不是进程而是作业。一个作业由多个进程组成。Shell可以运行一个前台作业和任意多个后台作业,称为作业控制。bash就是一个独立的作业。

进程组是一个或多个进程的集合,每个进程除了有一个PID以外,还有一个PGID。PGID就是组长的PID。进程组通常和一个作业相关联,可以接收来自同一个终端的信号。

当然,进程组和作业也并不是完全等价的两个概念:如果作业中某个进程有创建了新的子进程,该子进程不属于作业,但属于该进程组。

会话(Session)是一个或多个进程组的集合。一个会话可以有一个控制终端。一个会话中,有一个前台作业和若干个后台作业。会话SID是会话手进程的PID。

为什么只能运行一个前台作业?当我们在前台新起了一个作业,shell就被提到了后台,因此shell就没有办法再继续接受我们的指令并且解析运行了。但是如果前台进程退出了,shell就会有被提到前台来,就可以继续接受我们的命令并且解析运行。

那么,如何来切断进程和终端的关系呢?

首先,调用 setsid() 使子进程成为新的会话组长。setsid() 调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离。

调用setsid()有一个前提,就是该进程不能是一个组长进程,因此需要先fork并且杀死父进程,setsid ()的调用者是子进程。

接下来, 要禁止进程重新打开控制终端。能打开控制终端的进程一定是进程组组长,因此我们需要再次fork(),并且杀死父进程,留下的子进程就不再是话首进程和进程组组长。于是,这个子进程也不再拥有打开终端的权限,至此,我们彻底切断了该进程和终端的联系。

最后, 要关闭打开的文件描述符,或者对打开的文件描述符进行重定向。因为进程会继承从父进程那里的文件描述符,如果不关闭,会浪费系统的资源。

如果想改变该进程的所在目录,可以调用chdir(“/”) 将该守护进程转移到根目录。

如果该守护进程有子进程,那么守护进程需要等待子进程退出,否则子进程会变成僵尸进程。为了减少该守护进程的负担,防止其回收子进程对服务器并发性能的影响,可以使用signal(SIGCHLD, SIG_IGN) 对SIGCHLD忽略。这样就可以防止僵尸进程产生。

#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <sys syslog.h>
#include <sys param.h>
#include <sys types.h>
#include <sys stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int init_daemon(void)
{
    int pid;
    int i;

    // 1&#xFF09;&#x5C4F;&#x853D;&#x4E00;&#x4E9B;&#x63A7;&#x5236;&#x7EC8;&#x7AEF;&#x64CD;&#x4F5C;&#x7684;&#x4FE1;&#x53F7;
    signal(SIGTTOU,SIG_IGN);
    signal(SIGTTIN,SIG_IGN);
    signal(SIGTSTP,SIG_IGN);
    signal(SIGHUP ,SIG_IGN);

    // 2&#xFF09;&#x5728;&#x540E;&#x53F0;&#x8FD0;&#x884C;
    if( pid=fork() ){ // &#x7236;&#x8FDB;&#x7A0B;
        exit(0); //&#x7ED3;&#x675F;&#x7236;&#x8FDB;&#x7A0B;&#xFF0C;&#x5B50;&#x8FDB;&#x7A0B;&#x7EE7;&#x7EED;
    }else if(pid< 0){ // &#x51FA;&#x9519;
        perror("fork");
        exit(EXIT_FAILURE);
    }

    // 3&#xFF09;&#x8131;&#x79BB;&#x63A7;&#x5236;&#x7EC8;&#x7AEF;&#x3001;&#x767B;&#x5F55;&#x4F1A;&#x8BDD;&#x548C;&#x8FDB;&#x7A0B;&#x7EC4;
    setsid();

    // 4&#xFF09;&#x7981;&#x6B62;&#x8FDB;&#x7A0B;&#x91CD;&#x65B0;&#x6253;&#x5F00;&#x63A7;&#x5236;&#x7EC8;&#x7AEF;,&#x8FD9;&#x662F;&#x4E00;&#x79CD;&#x9632;&#x5FA1;&#x6027;&#x7F16;&#x7A0B;&#xFF0C;&#x662F;&#x53EF;&#x9009;&#x7684;&#x4E00;&#x6B65;
    if( pid=fork() ){ // &#x7236;&#x8FDB;&#x7A0B;
        exit(0);      // &#x7ED3;&#x675F;&#x7B2C;&#x4E00;&#x5B50;&#x8FDB;&#x7A0B;&#xFF0C;&#x7B2C;&#x4E8C;&#x5B50;&#x8FDB;&#x7A0B;&#x7EE7;&#x7EED;&#xFF08;&#x7B2C;&#x4E8C;&#x5B50;&#x8FDB;&#x7A0B;&#x4E0D;&#x518D;&#x662F;&#x4F1A;&#x8BDD;&#x7EC4;&#x957F;&#xFF09;

    }else if(pid< 0){ // &#x51FA;&#x9519;
        perror("fork");
        exit(EXIT_FAILURE);
    }

    // 5&#xFF09;&#x5173;&#x95ED;&#x6253;&#x5F00;&#x7684;&#x6587;&#x4EF6;&#x63CF;&#x8FF0;&#x7B26;
    // NOFILE &#x4E3A; <sys param.h> &#x7684;&#x5B8F;&#x5B9A;&#x4E49;
    // NOFILE &#x4E3A;&#x6587;&#x4EF6;&#x63CF;&#x8FF0;&#x7B26;&#x6700;&#x5927;&#x4E2A;&#x6570;&#xFF0C;&#x4E0D;&#x540C;&#x7CFB;&#x7EDF;&#x6709;&#x4E0D;&#x540C;&#x9650;&#x5236;
    for(i=0; i< NOFILE; ++i){
        close(i);
    }

    // 6&#xFF09;&#x6539;&#x53D8;&#x5F53;&#x524D;&#x5DE5;&#x4F5C;&#x76EE;&#x5F55;
    chdir("/tmp");

    // 7&#xFF09;&#x91CD;&#x8BBE;&#x6587;&#x4EF6;&#x521B;&#x5EFA;&#x63A9;&#x6A21;&#xFF0C;&#x56E0;&#x4E3A;&#x8FDB;&#x7A0B;&#x4ECE;&#x521B;&#x5EFA;&#x5B83;&#x7684;&#x7236;&#x8FDB;&#x7A0B;&#x90A3;&#x91CC;&#x7EE7;&#x627F;&#x4E86;&#x6587;&#x4EF6;&#x521B;&#x5EFA;&#x63A9;&#x6A21;&#x3002;&#x5B83;&#x53EF;&#x80FD;&#x4FEE;&#x6539;&#x5B88;&#x62A4;&#x8FDB;&#x7A0B;&#x6240;&#x521B;&#x5EFA;&#x7684;&#x6587;&#x4EF6;&#x7684;&#x5B58;&#x53D6;&#x6743;&#x9650;&#x3002;
    umask(0);

    // 8&#xFF09;&#x5904;&#x7406; SIGCHLD &#x4FE1;&#x53F7;
    signal(SIGCHLD,SIG_IGN);

    return 0;
}

int main(int argc, char *argv[])
{
    init_daemon();

    while(1);

    return 0;
}
</sys></time.h></stdlib.h></stdio.h></sys></sys></sys></sys></fcntl.h></signal.h></unistd.h>

Original: https://www.cnblogs.com/Grong/p/15750657.html
Author: 乌有先生ii
Title: 什么是守护进程?

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/585749/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Redis 位图BitMap

    应用场景: 用户签到 用户在线状态 统计活跃用户 各种状态值 自定义布隆过滤器 点赞功能 说明: 用string类型作为底层数据结构实现的一种统计状态的数据类型。 位图本质是数组,…

    Linux 2023年5月28日
    0108
  • RPA人力资源简历筛选机器人

    简历自动筛选及分析机器人,支持前程无忧、猎聘 1、自动登录招聘网站 2、自动填充简历筛选条件 3、RPA依次读取所筛选的简历信息 4、自动将简历数据复制到本地文档中 5、完成简历信…

    Linux 2023年6月7日
    0107
  • 解决微信Windows客户端无法播放视频问题

    问题描述 我的Windows端微信版本是3.6.0,更新后点开视频,没有播放按钮出现,并且过一会就会卡死,并且整个微信程序崩掉。 问题解决 后来发现,是微信客户端的 播放器插件问题…

    Linux 2023年6月14日
    0382
  • SQLI-LABS(Less-2)

    Less-2(GET-Error based-Intiger based) 打开 Less-2页面,可以看到页面中间有一句 Please input the ID as param…

    Linux 2023年6月6日
    091
  • 通过过滤器实现前后端分离的跨域问题

    跨域指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。在做前后端分离项目的时候就需要解决此问题。 创建过滤器解决跨域问…

    Linux 2023年6月7日
    0104
  • 网络安全之浅谈攻击

    最近大家也关注到了新闻,USA又对我国的一些总要的事业单位和网络基础设施进行的非法的攻击和渗透,窃取了大量的数据。可见看似和平静的水面,其实一直都是暗藏波涛,网络安全又被提摆到公众…

    Linux 2023年6月6日
    083
  • 【redis使用全解析】常见运维操作

    $ redis-server redis.conf 常见选项: ./redis-server (run the server with default conf) ./redis-…

    Linux 2023年5月28日
    076
  • X86 assembly guide

    This guide describes the basics of 32-bit x86 assembly language programming, covering a sm…

    Linux 2023年6月7日
    0142
  • c++智能指针的使用,shared_ptr,unique_ptr,weak_ptr

    c++智能指针的使用 官方参考 普通指针的烦恼:内存泄漏,多次释放,提前释放 智能指针 负责自动释放所指向的对象。 三种智能指针 shared_ptr,unique_ptr,wea…

    Linux 2023年6月14日
    0134
  • sql server 增删改(查太多了)

    delete(删除) 使用 delete语句删除表中数据。 delete from 表名 [where where_definition] 如果不使用where子句,将删除表中所有…

    Linux 2023年6月7日
    087
  • Redis做Mybatis的二级缓存

    基于spring boot项目的前提下,使用redis数据库做mybatis的二级缓存。 Redis做mybatis的二级缓存 作用提升速度,保证多台服务器访问同一数据库时不会崩注…

    Linux 2023年6月7日
    0117
  • jenkins 设置钉钉机器人+jenkins调用shell脚本使用钉钉机器人自定义发消息并通知指定人

    两种钉钉通知方式,一种是使用安装的钉钉插件来通知,但是这个不好定义通知内容,没办法控制发送条件,只要配置了,不管构建参数(分支,渠道,配置),都会发通知,第二种是使用脚本的方式来通…

    Linux 2023年5月28日
    093
  • Linux下腾达无线网卡U6的驱动安装

    U6无线网卡是rt8192eu芯片, 腾达驱动只支持到内核4.4左右; 5.0以上的内核就需要自己编译的。 终于找到了一个github修改版的驱动,经过验证运行正常。 https:…

    Linux 2023年6月14日
    088
  • 数据结构简单话(一)线性表

    前言 逻辑结构 物理存储结构 一、顺序表 二、链表 总结 前言 本菜鸟笔者打算入门一下数据结构,在学习过程中通过自己简单话术总结相关基础知识要点,希望能帮助同样在入门的小伙伴们快速…

    Linux 2023年6月7日
    0133
  • 北京思特奇2023年校招笔试(Java)

    北京思特奇2023年校招笔试(Java) 1、表达式 (short)10/10.2*2 运算后结果是什么类型? 答案:double,浮点数默认是double,自动类型向上转换为浮点…

    Linux 2023年6月14日
    098
  • MySQL slow log 慢日志

    sql慢日志用于记录执行时间超过指定阈值的SQL,对于系统性能和故障排错非常有帮助 1.如何开启sql慢日志 –&#x5F00;&#x542F;slow log …

    Linux 2023年6月6日
    078
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球