【Linux笔记】——进程间关系与守护进程

个人主页:孤寂大仙V
收录专栏:linux
往期回顾: 【计算机网络】应用层自定义协议与序列化反序列化——网络版本计算器
流水不争,争的是滔滔不息


一、进程组

进程组 = 一群可以一起接收信号的进程,它是 Linux 下进程管理的一个重要组织方式,尤其在 shell 控制、守护进程、kill 信号传递中非常有用。进程组是一个或者多个进程的集合,一个进程组可以包含多个进程。
【Linux笔记】——进程间关系与守护进程_第1张图片
写用一个管道写一个sleep的兄弟进程放到设置成后台任务,查看这个进程组的信息。这三个进程就属于一个进程组PGID相同。
组长进程
在上面图片中的PGID一列,发现sleep进程组的PGID等于第一个sleep进程的PID。每一个进程组都有一个组长进程,进程组id(PGID)=组长进程的id。

进程组组长的作用:进程组组长可以创建一个进程组或者创建该进程组中的进程。
进程组的生命周期是从进程组创建开始到其中最后一个进程离开。只有一个进程组中有一个进程存在,这个进程组就存在,与进程组的组长存不存在(是否终止)没关系。

进程组和任务的概念,任务就是某种工作,需要由进程来完成,进程组和任务可以理解为一个东西。

二、会话

【Linux笔记】——进程间关系与守护进程_第2张图片
**进程组是更小的单位。多个进程组组成一个会话(session)。**会话可以看作是多个进程组的集合。
在我们登录xshell的时候,完成登录认证,系统必须为用户新建一个会话,会话内部必须默认有一个进程组,叫做bash。在一个会话内,所有进程组的会话id(SID),都是这个进程组所处的会话的会话id。

通过键盘输入的数据,必须明确设置进程或者进程组。在会话内部,进程组必须区分为,前台进程和后台进程。 所以在一次会话中,有且只有一个前台进程组,后台进程可以有多个。一次会话中,有且只有一个前台任务,后台任务可以有多个。

当我们直接启动一个任务(进程组),这时这个任务是前台进程,就无法输入其他命令或进行其他操作了。因为这样直接启动的任务是前台进程。根据上面内容一个会话中只能有一个前台进程,接收命令的bash进程现在已经成后台进程了,没办法接收命令。把任务设置为后台执行,这是就可以执行其他命令与其他操作了。

作业控制

jobs查看系统当前的后台任务
fd+任务号,把指定的任务提到前台。
ctrl+c终止前台任务。
【Linux笔记】——进程间关系与守护进程_第3张图片

ctrl+z暂停进程或者进程组,且自动切换到后台。
bg+任务号,让后台进程运行起来。

守护进程

守护进程(Daemon Process)是指在后台运行、脱离终端控制、通常在系统启动时自动加载、长期运行的服务程序。

登录创建会话,关闭终端销毁会话,比如之前我们写的网络服务器,如果关闭终端了,会话就关了,会影响到服务器的运行。我们的服务器不能收到任何用户登录或者注销的影响。守护进程就是把这个进程组放到一个独立会话中,让任务成为独立会话内部的作业。
在 Linux 中,用户登录终端时会创建一个新的会话(Session),该会话中包含一个或多个进程组(Process Group)。一旦用户注销或关闭终端,该会话就会终止,所有隶属于该会话的前台和后台作业也会被系统自动终结。
对于如网络服务器这类应长期运行、稳定提供服务的程序,不能受到终端的控制或用户登录状态的影响。因此,我们需要将其转变为一个守护进程(Daemon),使其脱离控制终端、独立运行于自己的会话中。这样,即使用户退出登录,服务器进程仍能继续运行,稳定提供服务。

手写一个守护进程的接口

#pragma once

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "Log.hpp"
#include "Common.hpp"

using namespace LogModule;

const std::string dev = "/dev/null";

// 将服务进行守护进程化的服务
void Daemon(int nochdir, int noclose)
{
    // 1. 忽略IO,子进程退出等相关的信号
    signal(SIGPIPE, SIG_IGN);
    signal(SIGCHLD, SIG_IGN); // SIG_DFL

    // 2. 父进程直接结束
    if (fork() > 0)
        exit(0);

    // 3. 只能是子进程,孤儿了,父进程就是1
    setsid(); // 成为一个独立的会话

    if(nochdir == 0) // 更改进程的工作路径???为什么??
        chdir("/");

    // 4. 依旧可能显示器,键盘,stdin,stdout,stderr关联的.
    //  守护进程,不从键盘输入,也不需要向显示器打印
    //  方法1:关闭0,1,2 -- 不推荐
    //  方法2:打开/dev/null, 重定向标准输入,标准输出,标准错误到/dev/null
    if (noclose == 0)
    {
        int fd = ::open(dev.c_str(), O_RDWR);
        if (fd < 0)
        {
            LOG(LogLevel::FATAL) << "open " << dev << " errno";
            exit(OPEN_ERR);
        }
        else
        {
            dup2(fd, 0);
            dup2(fd, 1);
            dup2(fd, 2);
            close(fd);
        }
    }
}

系统中自带的

daemon(1, 1);

把之前写的网络版本计算器,服务器端守护进程化。
【Linux笔记】——进程间关系与守护进程_第4张图片
源码

你可能感兴趣的:(Linux,linux,笔记,运维)