守护进程+

一.进程组与会话

对于单个进程以及对应的PCB,我们之前已经大体全部讲过了,现在我们就来讲解进程组的概念

进程组:指的是一个或者多个进程的集合, 一个进程组可以包含多个进程。 每一
个进程组也有一个唯一的进程组 ID(PGID), 并且这个 PGID 类似于进程 ID, 同样是
一个正整数, 可以存放在 pid_t 数据类型中

补充:

pid:指当前进程的ID

ppid:指的是当前进程的父ID(可以为自身)

pgid:指的是当前进程的进程组ID

我们知道ps 指令可以查看当前系统运行的进程,下面我们认识两个新的选项:

-e 选项表示 every 的意思, 表示输出每一个进程信息
-o 选项以逗号操作符(,) 作为定界符, 可以指定要输出的列

如下图:

上面我们可以看出第二列是pgid,第二行和第三行属于同一个组,其中第二行pid=14528为组长进程,组长特点:pid=pgid

注意点:进程组的生命周期: 从进程组创建开始到其中最后一个进程离开为止。 注意:
主要某个进程组中有一个进程存在, 则该进程组就存在, 这与其组长进程是否已经终
止无关

会话:

定义:

会话可以看成是一个或多个进程组的集合, 一个会话可以包含多个进程组。 每一个会
话也有一个会话 ID(SID)

上图我们就可以看到sleep 10000/20000和30000属于同一个会话

会话如何创建呢?

在linux中有如下函数:

//头文件;
#include <unistd.h>

//函数:
pid_t setsid(void)
{};
//返回值:成功返回对应的sid,失败返回-1


//注意点:
//1.调用该函数的进程成为了新会话的话首进程,并且新的会话中目前只有一个进程,无bash
//2.调用的进程不能为话首进程,否则报错,我们可以fork通过子进程来调用



二.控制终端

在 UNIX 系统中, 用户通过终端登录系统后得到一个 Shell 进程, 这个终端成为 Shell
进程的控制终端。 控制终端是保存在 PCB 中的信息, 我们知道 fork 进程会复制 PCB
中的信息, 因此由 Shell 进程启动的其它进程的控制终端也是这个终端。 默认情况下
没有重定向, 每个进程的标准输入、 标准输出和标准错误都指向控制终端, 进程从标
准输入读也就是读用户的键盘输入, 进程往标准输出或标准错误输出写也就是输出到
显示器上。

注意点:

1.一个会话有最多一个终端,通常是话首进程打开一个终端(终端设备或伪终端设备) 后, 该终端就成为该会话的控制终端

2.建立与控制终端连接的会话首进程被称为控制进程
3.一个会话中多个进程组可以分为一个前台进程和多个后台进程
4.终端的终止等快捷键都是指向前台进程的

 


三.作业控制

定义:作业是针对用户来讲, 用户完成某项任务而启动的进程, 一个作业既可以只包含
一个进程, 也可以包含多个进程, 进程之间互相协作完成任务, 通常是一个进程
管道

Shell 分前后台来控制的不是进程而是作业 或者进程组。 一个前台作业可以由多
个进程组成, 一个后台作业也可以由多个进程组成, Shell 可以同时运⾏一个前台
作业和任意多个后台作业, 这称为作业控制

放在后台执⾏的程序或命令称为后台命令, 可以在命令的后面加上&符号从而让
Shell 识别这是一个后台命令, 后台命令不用等待该命令执⾏完成, 就可立即接收
新的命令, 另外后台进程执行完后会返回一个作业号以及一个进程号(PID)

如下图:

下面我们来认识一些指令控制后台:

&:表示将进程放后台运行(例如服务器,都是挂后台运行)

jobs:

-l:查看详细

-p:只显示pid

作业挂起:ctrl+z

作业切回:

fg 后面可以跟作业号或作业的命令名称。 如果参数缺省则会默认将作业号为 1 的作业切到前台来执⾏, 若当前系统只有一个作业在后台进⾏, 则可以直接使用 fg 命令不带参数直接切回

如下是将后台进程切回前台并终止操作



四.守护进程

定义:一类在后台运行的特殊进程,用于执行特定的系统任务。 很多守护进程在系统引导的时候启动,并且一直运行直到系统关闭。 另一些只在需要的时候才启动,完成任务后就自动结束

下面我们认识下deamon函数:


#include <unistd.h>
 
int daemon(int nochdir, int noclose);
//作用:创建守护进程
//参数:
//nochild:表示是从当前位置还是/位置开始
//noclose:是否进行输入输出的处理

关于该文件,可以看成垃圾站,任何都可以向其中写读,但是会自动清除,deamon重定向可以到该文件位置

下面我们手撕一个简单的deamon函数:

#include <iostream>
#include <cstdlib>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

void Deamon(bool ischdir,bool isclose)
{
    // 忽略可能引起程序异常退出的信号
    signal(SIGCHLD, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    //利用当前进程,创建子进程,保证自己不为组长
    pid_t pid =fork();
    if(pid>0)
    {
        //父进程
        exit(0);
    }
    //下面就是子进程了:
    //3设置让自己成为一个新的回话
    setsid();
    //下面修改参数部分:
    //ischdir:
    if(ischdir)
    {
        chdir(root);
    }
    //isclose
    if(isclose)
    {
        //不需要重定向,直接关闭
        close(0);
        close(1);
        close(2);
    }
    else
    {
        //需要重定向,dup2
        int fd=open(dev/null,O_RDWR);
        if(fd>0)
        {
            //打开文件成功:
            dup2(fd,0);
            dup2(fd,1);
            dup2(fd,2);
            close(fd);//关闭文件
        }
    }
}

利用deamon函数我们很容易就可以将服务进程守护进程化

以上就是守护进程的全部内容,感谢大家的支持!!!

猜你喜欢

转载自blog.csdn.net/2301_79813267/article/details/143168753