【Linux修炼】8.进程概念(二)

简介: 【Linux修炼】8.进程概念(二)

4.两种特殊的进程



4.1僵尸进程


上述已经提到过僵尸状态的进程的概念,那么在这里就详细演示一下僵尸进程的具体面貌:(代码)

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
int main()
{
    int id = fork();
    if(id > 0)
    {
        while(1)
        {
            printf("我是父进程,pid: %d, ppid: %d\n", getpid(), getppid());
            sleep(1);
        }
    }
    else if(id == 0)
    {
        while(1)
        {
            printf("我是子进程,pid: %d, ppid: %d\n", getpid(), getppid());
            sleep(1);
        }
    }
    else 
    {
        perror("fork fail");
        exit(-1);
    }
    return 0;
}


我们发现,通过sleep,为4044的子进程被杀掉了,此时父进程并没有处理子进程,因此出现了default(失效)并且子进程变成了Z状态,并且左侧也验证了只剩下父进程,并没有子进程的存在了!如果父进程一直不对这个子进程进行收取,那么这个子进程就会变成僵尸进程。


微信图片_20230225131125.png


4.2孤儿进程


1. 什么是孤儿进程?


上述我们提到,如果一个子进程被杀,那么其暂时就会处于僵尸状态,如果没有父进程回收就会变成僵尸进程。那如果是父进程被杀,父进程和子进程又会发生什么呢?事实上,父进程被杀,即父进程比子进程先退出,那么剩下的子进程就叫做孤儿进程。 这种现象也确实存在。


2.孤儿进程的表现形式


我们知道,如果一个进程变成了僵尸进程,其进程状态就会变成T,那我们来看看孤儿进程是如何表现的。


  1. 首先,我们仍然展示一下具体代码:(和僵尸进程中的代码一致)


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
int main()
{
    int id = fork();
    if(id > 0)
    {
        while(1)
        {
            printf("我是父进程,pid: %d, ppid: %d\n", getpid(), getppid());
            sleep(1);
        }
    }
    else if(id == 0)
    {
        while(1)
        {
            printf("我是子进程,pid: %d, ppid: %d\n", getpid(), getppid());
            sleep(1);
        }
    }
    else 
    {
        perror("fork fail");
        exit(-1);
    }
    return 0;
}


接下来,复制SSH渠道,杀掉父进程,观察子进程的状态。(父进程也关注一下)动图展示:


微信图片_20230225131240.gif

结果:

微信图片_20230225131245.png

我们发现,有三处发生了变化,其一是父进程被杀之后,变成了S状态,但是这样不就与我们之前的僵尸状态违背了吗?为什么不是T状态呢?事实上我们在上述僵尸状态中讲过,在被父进程回收之前就是T状态,而这个父进程被杀掉,也有其相应的父进程,这个父进程的父进程就是bash,bash相比较普通的父进程,bash进程将他的子进程进行了及时的回收,而这个父进程却不会对其子进程进行及时的回收。因此对比之下bash进程比一般的父进程更加负责。


其二就是我们子进程的状态,由S+变成了S进程,即从前台进程变成了后台进程,这就是孤儿进程最明显的变化,变成后台进程后不能通过ctrl c快捷键暂停,而只能通过kill结束进程(当然,断电处理也可以,但是没必要)


其三我们发现,子进程的PPID也就是这个子进程的父进程因为被杀掉而变成了1,而这个1所对应的其实就是操作系统,即父进程被杀掉之后,这个子进程被操作系统所领养,操作系统就变成了他的父进程,这也正对应了冯诺依曼体系中的进程被操作系统所管理。如果不领养,那么当这个子进程被杀掉时,就会因为没有后续处理从而将变成僵尸进程,这是整个体系都不愿看到的结果,因此操作系统必须领养。



5.进程优先级(了解范畴)



对于进程优先级,我们采取三个问题将这个概念解释清楚:


1. 什么叫做优先级?


只凭字面意思来说,优先级和权限有没有区别呢?答案是一定有的,即权限是能做或者不能做的问题,而优先级是先做和后做的问题。


2. 为什么会存在优先级?


那为什么会存在优先级呢?那是因为在一定范围内的资源是有限的,为了获得这个资源就必须赶在其他人的前面,否则就有可能最后什么也捞不到。举个例子:我们知道在一个内存中有许多的进程,但是CPU只有一个,这个时候进程为了能够先执行就会产生优先级的概念,即重要的进程先运行,其他的进程后运行。


3. Linux优先级的特点


在Linux操作系统中,在ps ajx 选项中出现的PRI(priority)下的数字就是所谓的优先级,即这个数字和我们现实中的排名一样,数值越低,优先级就越高。而这个数值PRI = 基础数值(80) + nice值,(NI)nice值是可以进行修改的,其修改区间为[-20,19],因此PRI的范围为[60, 99]。


仍然是利用孤儿进程的代码:

演示:通过指令ps -l PID


微信图片_20230225131356.png

我们发现,初始状态下,PRI和NI的值为80和0,加起来就是基础数值。

接下来进行修改:

通过如下指令:进入top后按“r”–>输入进程PID–>输入nice值

第一步:sudo top(改变优先级需要提权)

微信图片_20230225131400.png


第二步:输入r,输入对应要修改优先级进程的PID,回车


微信图片_20230225131443.png

第三步:输入修改之后的NI值。回车。

微信图片_20230225131446.png

这样就修改完成了,接下来我们看一看结果:

微信图片_20230225131449.png

这样其PRI就变成了80+19 = 99。


6.进程的其他概念



竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级

独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰

并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行

并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发(一段时间采用:时间片轮转的方式)


7.进程切换



在定义之前,我们需要举例引入进程切换的概念,对于我们常用的手机、电脑等,一般只有一个CPU,我们知道一个CPU一次只能运行一个进程,但是我们发现,在电脑上,我们可以在打开PDF的同时,去浏览一些其他网页,即同一个时间段内,多个进程可以被CPU同时运行,这是为什么呢?事实上这就是进程切换的效果。


进程切换的理解: 由于Linux的CPU一次只能运行一个进程,但是我们一个时间段内却可以运行多个进程,因为CPU是足够快的,因此我们人感觉的一瞬间就相当于CPU的一个时间段,想一想1ms对于人来说算是一瞬间,但是CPU却是以纳秒为单位计时的,因此在我们自身感觉到的一瞬间也就是CPU的一个时间段内,会将执行的多个进程按照一定的周期分别运行,一个运行到固定周期之后就强行拉入运行队列的末尾等待,就这样直到完成所有执行的进程,这就是进程之间在一定的时间内相互切换,叫做进程切换。而所谓的周期就是时间片。(并发中提到)


进程的上下文保护:


当CPU在进行进程切换的时候,要进行进程的上下文保护,当进程在恢复运行的时候,要进行上下文进程的恢复!


上下文是什么呢?


进程在运行时会产生非常多的临时数据,同时CPU中存在一套寄存器硬件,当进程运行时,进程的PCB会被放入CPU内的寄存器中,此时CPU就可以通过进程PCB(暂时理解成PCB)得到进程代码数据的地址;CPU在运行进程时所产生的大量的临时数据也都会被保存在寄存器中;因此在进行进程切换时需要进行进程的上下文保护与上下文恢复,进程停止运行时将寄存器里面的数据保存起来,进程重新运行时将保存的数据再放入到寄存器中;所以进程的上下文就是一个进程完成他的时间片后在CPU中所保存的临时数据。



相关文章
|
23天前
|
算法 Linux 调度
深入理解Linux操作系统的进程管理
本文旨在探讨Linux操作系统中的进程管理机制,包括进程的创建、执行、调度和终止等环节。通过对Linux内核中相关模块的分析,揭示其高效的进程管理策略,为开发者提供优化程序性能和资源利用率的参考。
54 1
|
2月前
|
资源调度 Linux 调度
Linux c/c++之进程基础
这篇文章主要介绍了Linux下C/C++进程的基本概念、组成、模式、运行和状态,以及如何使用系统调用创建和管理进程。
50 0
|
11天前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
66 13
|
18天前
|
SQL 运维 监控
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
|
27天前
|
调度 开发者
核心概念解析:进程与线程的对比分析
在操作系统和计算机编程领域,进程和线程是两个基本而核心的概念。它们是程序执行和资源管理的基础,但它们之间存在显著的差异。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
50 4
|
26天前
|
运维 监控 Linux
Linux操作系统的守护进程与服务管理深度剖析####
本文作为一篇技术性文章,旨在深入探讨Linux操作系统中守护进程与服务管理的机制、工具及实践策略。不同于传统的摘要概述,本文将以“守护进程的生命周期”为核心线索,串联起Linux服务管理的各个方面,从守护进程的定义与特性出发,逐步深入到Systemd的工作原理、服务单元文件编写、服务状态管理以及故障排查技巧,为读者呈现一幅Linux服务管理的全景图。 ####
|
1月前
|
缓存 监控 Linux
linux进程管理万字详解!!!
本文档介绍了Linux系统中进程管理、系统负载监控、内存监控和磁盘监控的基本概念和常用命令。主要内容包括: 1. **进程管理**: - **进程介绍**:程序与进程的关系、进程的生命周期、查看进程号和父进程号的方法。 - **进程监控命令**:`ps`、`pstree`、`pidof`、`top`、`htop`、`lsof`等命令的使用方法和案例。 - **进程管理命令**:控制信号、`kill`、`pkill`、`killall`、前台和后台运行、`screen`、`nohup`等命令的使用方法和案例。
147 4
linux进程管理万字详解!!!
|
1月前
|
缓存 算法 Linux
Linux内核的心脏:深入理解进程调度器
本文探讨了Linux操作系统中至关重要的组成部分——进程调度器。通过分析其工作原理、调度算法以及在不同场景下的表现,揭示它是如何高效管理CPU资源,确保系统响应性和公平性的。本文旨在为读者提供一个清晰的视图,了解在多任务环境下,Linux是如何智能地分配处理器时间给各个进程的。
|
1月前
|
存储 运维 监控
深入Linux基础:文件系统与进程管理详解
深入Linux基础:文件系统与进程管理详解
87 8
|
1月前
|
网络协议 Linux 虚拟化
如何在 Linux 系统中查看进程的详细信息?
如何在 Linux 系统中查看进程的详细信息?
102 1