Linux--任务管理与守护进程

news2024/11/14 2:02:44

目录

任务管理

进程组概念

作业概念

会话概念

补充

守护进程

基本概念

守护进程的查看

守护进程的创建

自己手写守护进程

使用系统调用函数创建守护进程


任务管理

进程组概念

  • 每一个进程除了有一个进程ID之外,还有一个进程组ID,进程组是一个或多个进程的集合
  • 通常它们与同一个作业相关联,可以接收来自同一个终端的各种信号。每个进程组都有一个唯一的进程组ID。每一个进程组都有一个组长进程。组长进程ID==进程组ID。组长进程可以创建一个进程组,创建该组中的进程,然后终止。
  • 需要注意,只要在某个进程组中有一个进程存在,则该进程就存在,这与组长进程是否存在没有关系。

作业概念

  • Shell分前后台来控制的不是进程而是作业(Job)或者进程组(Process Group).
  • 一个前台作业可以有多个进程组成,Shell可以运行一个前台作业和多个后台作业,这称为作业控制。
  • 作业与进程的区别:如果作业中某个进程又创建了子进程,则子进程不属于作业。一旦作业运行结束,Shell就把自己提到前台,如果原来的前台进程还存在,也就是这个被创建的子进程还没有终止,那么它就将自动变为后台进程组。

会话概念

  • 会话(Session)是一个或多个进程组的集合。
  • 一个会话可以又一个控制终端,这里通常是登录到其他设备的终端(在终端登录情况下)或伪终端设备(在网络登录情况下)。建立于控制终端连接的会话进程被称为控制进程。一个会话中的进程组可以被分为一个前台进程组以及多个后台进程组。
  • 会话也有ID用来标识,这里会话ID==bash的PID。

补充

(1)前台进程和后台进程

前台进程: ./运行时,默认将程序放到前台执行,在前台运行时,进程状态后面会有一个+号

后台进程: ./XXX & .在执行可执行程序时在后面加上 & 。就时将程序放到后台执行。进程的状态后面没有+号。

这里我们将程序放到后台执行我们会发现多了一行提示信息。

这里[3]时作业编号,如果同时运行多个作业可以用这个编号区分,23612时该作业中某个进程的PID(一个作业可以由多个进程组成)。

对于前后台进程经常使用到的命令

jobs  //查看当前会话中由哪些作业
fg 后台进程编号 //将编号对应的作业提至前台运行
bg 后台进程编号 //可以让某个停止的作业到后台重新运行

关于会话

  • 当我们用一个Xshell或者终端登录时,本质都是先创建一个bash进程,整体称之为一个会话(所有的命令行的进程都是bash的子进程),所有的命令行启动的任务都是在对应的会话内运行的。
  • 实际我们每一次登录的过程都是新建会话的过程,同一个会话中的所有进程的SESS是相同

守护进程

基本概念

  • 守护进程也称精灵进程(Daemon),是运行在后台的一种特殊进程,它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。
  • 为了保证一个任务,当终端会话退出的时候,这个任务还在服务后端跑,所以我们需要一种进程叫守护进程
  • 守护进程是一种很有用的进程,Linux的大多数服务器就是用守护进程实现的,比如Internet服务器inetd,Web服务器httpd等。同时守护进程完成许多系统任务,比如作业规划进程crond等。
  • Linux系统启动时会启动很多系统服务进程,这些系统服务进程没有控制终端,不能直接和用户交互。其他进程都是在用户登录或运行程序时创建,在运行结束或用户注销时终止,但系统服务进程不受用户登录注销的影响,它们一直在运行着,这种进程有一个名称叫守护进程(Daemon)。

守护进程的查看

  • 参数a表示不仅列出当前用户的进程,也列出所有其他用户的进程。
  • 参数x表示不仅列出有控制终端的进程,也列出所有无控制终端的进程。
  • 参数j表示列出与作业控制相关的信息

  • 凡是TPGID一栏写着-1的都是没有控制终端的进程,也就是守护进程
  • 除此之外,在COMMAND一列用[ ]括起来的名字表示内核线程,这些线程在内核里创建,没有用户空间代码,因此没有程序文件名和命令行,通常采用以k开头的名字,表示Kernel。
  • 个别说明:udevd负责维护/dev目录下的设备文件 ,acpid负责电源管理 , syslogd负责维护/var/log下的日志文件。
  • 可以看出,守护进程通常采用以d结尾的名字,表示Daemon。

守护进程的创建

自己手写守护进程

创建思路:

  • 1.设置文件掩码为0.
  • 2.fork后终止父进程,子进程调用setsid创建新会话。
  • 3.忽略SIGCHLD信号。
  • 4.更改工作目录为根目录。
  • 5.将标准输入,标准输出,标准错误重定向到/dev/null。

解释:

  • 1.将文件掩码设置为0,是为了保证后续创建进程是,创建出来的文件权限符合我们的预期。
  • 2.setsid函数创建新会话的目的是,让当前进程自成会话,与目前bash脱离关系(即关闭当前页面进程仍可以在我们的云服务器上运行)。这也是创建守护进程的核心。
  • 3.之所以让子进程调用setside创建新会话,是因为创建新会话的进程不能是组长进程,但是当我们在命令行上启动多个进程协同完成一个任务时,第一个被我们创建的进程就是组长进程,所以这里我们使用fork创建子进程,让子进程调用setsid创建新的会话并继续执行后续代码,而父进程直接退出。
  • 4.我们一般会将守护进程的工作目录设置为根目录,便于让守护进程以绝对路径的形式访问某种资源。(该操作不是必须的)
  • 6.守护进程不能直接和用户交互,也就是说守护进程已经与终端去关联了,因此一般我们会将守护进程的标准输入、标准输出以及标准错误都重定向到/dev/null,/dev/null是一个字符文件(设备),通常用于屏蔽/丢弃输入输出信息。(该操作不是必须的)

守护进程代码(Demon.hpp):

#pragma once

#include <iostream>
#include <string>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<cstdlib>
const std::string nullfile = "/dev/null";

void Demon(const std::string &cwd = "")
{
    // 忽略其他异常信号
    signal(SIGPIPE, SIG_IGN);
    signal(SIGCHLD, SIG_IGN);
    signal(SIGSTOP, SIG_IGN);

    // 2.将自己变为独立的会话
    // 因为进程组的组长无法调用系统调用函数setsid,所以这里采用fork创建子进程,
    // 让父进程直接结束,子进程创建独立的会话,并执行下面的代码
    if (fork() > 0)
        exit(0);

    setsid(); // 子进程创建独立的会话

    // 改变进程所在目录
    if (!cwd.empty())
    {
        chdir(cwd.c_str());
    }

    // 将标准输入,输出,错误重定向到/dev/null文件,这个文间相当于垃圾站
    int fd = open(nullfile.c_str(), O_RDWR);
    if (fd > 0)
    {
        dup2(fd, 0);
        dup2(fd, 1);
        dup2(fd, 2);
        close(fd);
    }
}

测试代码(test.cpp):

#include<iostream>
#include"Demon.hpp"

int main()
{

    Demon();
    while(1)
    {
        std::cout<<"1adasd"<<std::endl;
        sleep(1);
    }

    return 0;
}

这里我们启动进程后可以使用指令:

//该指令用来查看我们的守护进程是否真的运行起来了
ps -ajx | head -1 && ps -ajx | grep test

  • 这里我们可以发现使用ps产看给进程的信息时,发现给进程的TTY为?,意味着该进程与终端失去关联。
  • test进程的SID与grep进程的SID不同,即它们不属于同一个会话。

同时我们也可以使用指令:

//查看该进程的标准输出,输入,错误是否已经重定向到/dev/null
ls /proc/进程PID/fd -al

使用系统调用函数创建守护进程

我们创建守护进程时可以直接调用daemon接口进行创建,daemon函数的函数原型如下:

int daemon(int nochdir, int noclose);

参数说明:

  • 如果参数nochdir为0,则将守护进程的工作目录该为根目录,否则不做处理。
  • 如果参数noclose为0,则将守护进程的标准输入、标准输出以及标准错误重定向到/dev/null,否则不做处理。

例子:

#include<iostream>
#include<unistd.h>

int main()
{

    daemon(0,0);
    while(1)
    {
        std::cout<<"1adasd"<<std::endl;
        sleep(1);
    }

    return 0;
}

  • 这里调用系统调用函数daemon创建的守护进程与我们手动创建的守护进程区别不大。唯一的区别就是,daemon函数创建的守护进程即使组长进程,又是会话首进程。
  • 系统调用的进程没有防止守护进程打开终端

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1545655.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

由浅到深认识Java语言(29):集合

该文章Github地址&#xff1a;https://github.com/AntonyCheng/java-notes 在此介绍一下作者开源的SpringBoot项目初始化模板&#xff08;Github仓库地址&#xff1a;https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址&#xff1a;https://blog.c…

光致发光荧光量子产率测试光纤光谱仪

光致发光荧光量子产率测试系统是一种用于测量材料发光效率的高精度设备&#xff0c;它通过光致发光方法来确定样品的发射效率。光致发光荧光量子产率测试系统不仅提供了一种高效、可靠的测量手段&#xff0c;而且对于提升科学研究和工业应用中的发光材料性能具有重要作用。通过…

Python:基础语法

一、import与from.....import 有时候我们需要使用一些第三方库或包时&#xff0c;我们就需要通过import或from.....import导入模块。 # 导入库 import sys print("hello,world") 当我们自己写了些函数&#xff0c;在其他py文件&#xff0c;我们也可以通过from.....im…

【Java程序设计】【C00361】基于Springboot的考勤管理系统(有论文)

基于Springboot的考勤管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 项目获取 &#x1f345;文末点击卡片获取源码&#x1f345; 开发环境 运行环境&#xff1a;推荐jdk1.8&#xff1b; 开发工具&#xff1a;eclipse以及idea&…

「10」文本(GDI+):添加文字,可设置背景添加移动效果

「10」文本&#xff08;GDI&#xff09;添加文字&#xff0c;可设置背景添加移动效果 在OBS软件里&#xff0c;通过来源组件「文本&#xff08;GDI&#xff09;」&#xff0c;您可以添加任意您想要呈现的文字&#xff0c;在直播窗口中显示&#xff0c;它可以是提示语、广告词、…

SQLServer SEQUENCE用法

SEQUENCE&#xff1a;数据库中的序列生成器 在数据库管理中&#xff0c;经常需要生成唯一且递增的数值序列&#xff0c;用于作为主键或其他需要唯一标识的列的值。为了实现这一功能&#xff0c;SQL Server 引入了 SEQUENCE 对象。SEQUENCE 是一个独立的数据库对象&#xff0c;用…

python.类

1.类用class定义 name等是属性 是成员变量 定义完类了要定义对象 class Student: #定义了一个Student的类nameNoneageNonegenderNonesdu1Student() #创建了一个Student类的对象 sdu1.nameleo sdu1.age20 sdu1.gendermaleprint(sdu1.name) print(sdu1.age) print(sdu1.…

Day21|二叉树part07:530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先

530. *二叉搜索树的最小绝对差&#xff08;双指针题型&#xff09; 众所周知二叉搜索树的中序遍历序列是一个有序数组&#xff0c;因此最基本的方法就是遍历得到中序序列再进行计算&#xff0c;实际上可以用双指针法&#xff0c;记录中序遍历前一个指针和当前指针的差值&#…

一个bitter组织下载器样本分析

BITTER 该组织最早在2016由美国安全公司Forcepoint进行了披露&#xff0c;并且命名为“BITTER”&#xff0c;同年国内友商360也跟进发布了分析报告&#xff0c;命名为“蔓灵花” 样本分析 MD5&#xff1a;806626d6e7a283efffb53b3831d53346 vt:看文件名判断是伪装成pdf的自解…

小学生古诗文大会往届真题测一测(来自主办方)和非常详细的解析

新学期开学一眨眼已经过了一个多月了&#xff0c;有家长朋友开始关心2024年上海市小学生古诗文大会什么时候开始&#xff1f;如何准备小学生古诗文大会&#xff1f;如何激发孩子学习古诗词的兴趣&#xff1f;如何提高小学古诗词和古诗文大会的学习成绩&#xff1f;... 最近&…

YT8531调试记录

总结 还是从设备树&#xff0c;mac驱动&#xff0c;mac驱动对mdio总线的注册&#xff0c;phy驱动 &#xff0c;phy的datasheet&#xff0c;cpu的datasheet 几个方面来看来看 0.确认供电&#xff0c;以及phy的地址(一般会有多个地址&#xff0c;根据相关引脚电平可配置) 1.确…

Linux离线安装mysql,node,forever

PS:本文是基于centos7实现的,要求系统能够查看ifconfig和unzip解压命令, 实现无网络可安装运行 首先现在百度网盘的离线文件包****安装Xftp 和 Xshell 把机房压缩包传到 home目录下****解压unzip 包名.zip 获取IP先获取到 linux 主机的ip ifconfig Xftp 连接输入IP,然后按照…

CentOS使用Docker部署Halo并结合内网穿透实现公网访问本地博客

文章目录 1. Docker部署Halo1.1 检查Docker版本如果未安装Docker可参考已安装Docker步骤&#xff1a;1.2 在Docker中部署Halo 2. Linux安装Cpolar2.1 打开服务器防火墙2.2 安装cpolar内网穿透 3. 配置Halo个人博客公网地址4. 固定Halo公网地址 本文主要介绍如何在CentOS 7系统使…

搭建本地局域网域名并配置本地的mqtt服务器

1. 第一步&#xff1a; 首先准备一台windows电脑&#xff0c;安装 Technitium DNS Server 链接如下&#xff1a; Technitium DNS Server | An Open Source DNS Server For Privacy & Security 启动 start 然后进入 http://localhost:5380/ 下载完成之后&#xff0c;需要…

内网端口如何映射到外网?

内网端口映射到外网是一项重要的网络技术&#xff0c;它可以实现在任何网络环境下远程访问和管理内网设备。在复杂的网络环境中&#xff0c;内网设备通常无法直接被外网访问&#xff0c;而内网端口映射技术可以解决这个问题。本文将介绍一种名为【天联】的组网产品&#xff0c;…

最小割问题合集,最大权闭合图,最大密度子图,最小权点覆盖,最大权独立子图,OJ练习,代码详解

文章目录 零、回顾1、流网络的割2、最小割问题 一、最小割的应用1.1POJ1966 -- Cable TV Network1.1.1原题链接1.1.2思路分析1.1.3AC代码 1.2ZOJ 2676 Network Wars1.2.1原题链接1.2.2思路分析1.2.3AC代码 1.3OPTM - Optimal Marks1.3.1原题链接1.3.2思路分析1.3.3AC代码 二、最…

VS2022 nuget 无法解析 PackageSourceMapping 已启用,未考虑以下源: nuget.org。

前言&#xff1a; VS中的项目包的指向是 nuget.org&#xff0c;不是本地的下载后包。 解决方法&#xff1a; 把“包源映射”里的全部移除。

tcp/ip是什么意思,tcp/ip协议包含哪几层

TCP/IP是一种网络通信协议&#xff0c;它是互联网所采用的基本协议。TCP/IP协议是由美国国防部高级研究计划局&#xff08;ARPA&#xff09;在上世纪70年代设计开发的&#xff0c;经过多年发展和完善&#xff0c;已成为全球范围内最重要的网络通信协议之一。 首先&#xff0c;让…

Gif动图怎么快速制作?两招教你在线做

Gif动图作为一种实用的图片格式&#xff0c;因为其体积小&#xff0c;画面丰富&#xff0c;所以在各大聊天软件中非常的受欢迎。小伙伴们是不是很好奇这种gif动态图片是如何制作的吧&#xff01;下面&#xff0c;小编就给大家分享两个快速制作gif动画的小技巧&#xff01;不用下…

UI 自动化里面等待方式应用场景!

掌握Selenium 自动化测试的人员都知道Selenium的等待使用场景至关重要&#xff0c;这些等待对于测试自动化稳定性不可或缺的一部分&#xff0c;因为它们确保与 Web 元素的同步交互&#xff0c;从而能够在不同的加载时间和动态页面更改中准确执行测试脚本。 本文将深入探讨 Sel…