Linux - 进程的概念、状态、僵尸进程、孤儿进程及进程优先级

目录

进程基本概念

描述进程-PCB

  task_struct-PCB的一种

  task_struct内容分类

查看进程

  通过系统目录查看

  通过ps命令查看

通过系统调用获取进程的PID和PPID

通过系统调用创建进程- fork初始

  fork函数创建子进程

  使用if进行分流

Linux进程状态

  运行状态-R

  浅度睡眠状态-S

  深度睡眠状态-D

  暂停状态-T

  僵尸状态-Z

  死亡状态-X

僵尸进程

  僵尸进程的危害

孤儿进程

进程优先级

  基本概念

  查看系统进程

  PRI与NI

  查看进程优先级信息

  通过top命令更改进程的nice值

步骤:

示例:

  通过renice命令更改进程的nice值

命令语法:

示例:

  四个重要概念


进程基本概念

        课本概念:在编程或软件工程的上下文中,进程通常被视为正在执行的程序的实例。当你启动一个应用程序时,操作系统会为这个程序创建一个进程。每个进程都有自己的独立内存空间,可以运行自己的指令序列,并可能与其他进程通信。进程是操作系统管理程序执行的基本单位。

        程序的一个执行实例,正在执行的程序等。

        内核观点:从操作系统的内核角度来看,进程是一个重要的抽象,用于封装执行环境和状态。内核必须跟踪每个进程的状态,包括它的内存映射、打开的文件、资源使用情况(如CPU时间、内存),以及进程的优先级和调度信息。内核通过进程调度算法决定哪个进程在特定时刻可以使用CPU,以及如何分配有限的系统资源给多个竞争的进程。

        担当分配系统资源(CPU时间,内存)的实体。

        每个程序员都清楚,当源代码经过编译和链接阶段,会转换成一个可直接运行的二进制文件,即我们通常所说的可执行程序。这个文件实质上就是存储在硬盘上的指令集合。然而,当我们通过双击这个可执行文件来启动它时,真正的动作是在操作系统层面将这些指令加载到计算机的随机存取存储器(RAM)中。这是因为中央处理器(CPU)只能直接访问内存中的指令,从而逐条执行它们。因此,一旦这个程序驻留在内存里,它的身份就发生了转变——从一个静态的“程序”变成了一个动态的“进程”。在操作系统术语中,这种状态下的程序被称为进程,它包含了执行环境以及与之相关的所有资源。

描述进程-PCB

        系统当中可以同时存在大量进程,使用命令ps aux便可以显示系统当中存在的进程。

        当计算机启动时,最先唤醒的是操作系统,它如同一位总指挥,负责调度和管理计算机的各种资源与活动。在众多任务中,进程管理尤为关键,因为计算机内部同时运行着成百上千个进程,每个进程都是执行中的程序实例。 

那么操作系统是如何对进程进行管理的呢?

  • 操作系统采用了一种高效且有序的方式来管理这些进程,这个过程可以精炼为“先描述 再组织”。首先,每当一个新的进程诞生,操作系统立即创建其“身份证明”,也就是进程控制块(PCB)。PCB 是一个数据结构,它记录了进程的所有重要信息,如进程状态、优先级、内存使用情况、打开的文件等,相当于进程的个人档案。
  • 接下来,操作系统的进程管理功能通过这些PCB来跟踪和控制进程的状态变化。无论是分配CPU时间、调整进程优先级、还是处理进程间的通信,都基于对PCB信息的读取和修改。这样,操作系统无需直接与每个进程交互,而是通过对PCB的高效管理,实现了对所有进程的精准调控,确保了系统资源的合理分配和利用,以及程序的顺利执行。

        操作系统为了有效地管理和追踪每个进程,采用了一种精妙的策略,即将每个进程的信息封装在一个称为进程控制块(PCB)的结构中。这些PCB并非孤立存在,它们被精心地组织成一个双链表结构,使得操作系统可以通过维护这个列表的头部指针,轻松访问和遍历整个进程集合。

        这种设计赋予了操作系统强大的管理能力。例如,当需要创建一个新进程时,操作系统首先将该进程的代码和数据载入内存,随后为这个进程生成一个详细的PCB,并将其无缝地插入到双链表中,这一操作实质上标志着新进程的正式加入。

        相反,当一个进程完成使命或需要终止时,操作系统会首先定位并移除对应的PCB,从而将其从双链表中剔除。接着,操作系统会清理内存中属于该进程的资源,释放它们供其他进程使用,或者将这些区域标记为可用状态。

        因此,操作系统对进程的整个生命周期管理,实质上转化为对双链表的高效操作,包括但不限于添加、删除、查找和更新PCB。这种抽象层次的提升,不仅简化了操作系统的实现,也保证了系统资源的有效管理和进程间的顺畅协调。

  task_struct-PCB的一种

        进程控制块(PCB)是操作系统用于描述和管理进程的关键数据结构。在C++中,类似的概念可通过类来实现,但在C语言环境下,如Linux操作系统,PCB则是通过结构体(struct)来具体实现的。这意味着Linux内核中的PCB是一个包含多种信息字段的结构体,用于存储关于进程状态的所有必要数据。

  • PCB实际上是对进程控制块的统称,在Linux中描述进程的结构体叫做task_struct。
  • task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含进程的信息。

  task_struct内容分类

        在Linux操作系统中,task_struct充当着进程控制块的角色,它是一个综合性的数据结构,用于封装与进程管理相关的所有关键信息。

以下是task_struct中主要包含的几类信息:

  • 标示符: 描述本进程的唯一标示符,用来区别其他进程。
  • 状态: 任务状态,退出代码,退出信号等。
  • 优先级: 相对于其他进程的优先级。
  • 程序计数器(pc): 程序中即将被执行的下一条指令的地址。
  • 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。
  • 上下文数据: 进程执行时处理器的寄存器中的数据。
  • I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
  • 记账信息: 可能包括处理器时间总和,使用的时钟总和,时间限制,记账号等。
  • 其他信息。

查看进程

  通过系统目录查看

        在根目录下有一个名为proc的系统文件夹。

        文件夹当中包含大量进程信息,其中有些子目录的目录名为数字。

 

        这些数字其实是某一进程的PID,对应文件夹当中记录着对应进程的各种信息。我们若想查看PID为1的进程的进程信息,则查看名字为1的文件夹即可。 

  通过ps命令查看

        单独使用ps命令,会显示所有进程信息。

russleo@VM-0-2-ubuntu:/$ ps aux

 

        ps命令与grep命令搭配使用,即可只显示某一进程的信息。 

russleo@VM-0-2-ubuntu:/$ ps aux | head -1 && ps aux | grep bash | grep -v grep

通过系统调用获取进程的PID和PPID

        通过使用系统调用函数,getpid和getppid即可分别获取进程的PID和PPID。

        当运行该代码生成的可执行程序后,便可循环打印该进程的PID和PPID。 

        我们可以通过ps命令查看该进程的信息,即可发现通过ps命令得到的进程的PID和PPID与使用系统调用函数getpid和getppid所获取的值相同。 

通过系统调用创建进程- fork初始

  fork函数创建子进程

        fork是一个系统调用级别的函数,其功能就是创建一个子进程。

        若是代码当中没有fork函数,我们都知道代码的运行结果就是循环打印该进程的PID和PPID。而加入了fork函数后,代码运行结果如下: 

        运行结果是循环打印两行数据,第一行数据是该进程的PID和PPID,第二行数据是代码中fork函数创建的子进程的PID和PPID。我们可以发现fork函数创建的进程的PPID就是proc进程的PID,也就是说proc进程与fork函数创建的进程之间是父子关系。 

        每出现一个进程,操作系统就会为其创建PCB,fork函数创建的进程也不例外。 

        我们知道加载到内存当中的代码和数据是属于父进程的,那么fork函数创建的子进程的代码和数据又从何而来呢? 

        实际上,使用fork函数创建子进程,在fork函数被调用之前的代码被父进程执行,而fork函数之后的代码,则默认情况下父子进程都可以执行。需要注意的是,父子进程虽然代码共享,但是父子进程的数据各自开辟空间(采用写时拷贝)。

注意: 使用fork函数创建子进程后就有了两个进程,这两个进程被操作系统调度的顺序是不确定的,这取决于操作系统调度算法的具体实现。

  使用if进行分流

        上面说到,fork函数创建出来的子进程与其父进程共同使用一份代码,但我们如果真的让父子进程做相同的事情,那么是不是创建子进程就没有什么意义了。

        实际上,在fork之后我们通常使用if语句进行分流,即让父进程和子进程做不同的事。

fork函数的返回值:
1、如果子进程创建成功,在父进程中返回子进程的PID,而在子进程中返回0。
2、如果子进程创建失败,则在父进程中返回 -1。 

        既然父进程和子进程获取到fork函数的返回值不同,那么我们就可以据此来让父子进程执行不同的代码,从而做不同的事。 

        fork创建出子进程后,子进程会进入到 if 语句的循环打印当中,而父进程会进入到 else if 语句的循环打印当中。

Linux进程状态

        一个进程从创建而产生至撤销而消亡的整个生命期间,有时占有处理器执行,有时虽可运行但分不到处理器,有时虽有空闲处理器但因等待某个时间的发生而无法执行,这一切都说明进程和程序不相同,进程是活动的且有状态变化的,于是就有了进程状态这一概念。

        这里我们具体谈一下Linux操作系统中的进程状态,Linux操作系统的源代码当中对于进程状态有如下定义: 

/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char *task_state_array[] = 
{"R (running)",       /*  0*/"S (sleeping)",      /*  1*/"D (disk sleep)",    /*  2*/"T (stopped)",       /*  4*/"T (tracing stop)",  /*  8*/"Z (zombie)",        /* 16*/"X (dead)"           /* 32*/
};

注意: 进程的当前状态是保存到自己的进程控制块(PCB)当中的,在Linux操作系统当中也就是保存在task_struct当中的。 

        在Linux操作系统当中我们可以通过 ps aux 或 ps axj 命令查看进程的状态。 

        STAT所在列表示运行状态。

russleo@VM-0-2-ubuntu:~$ ps aux

russleo@VM-0-2-ubuntu:~$ ps axj

  运行状态-R

        进程处于运行状态意味着它正准备运行或正在运行。这包括进程正在等待CPU时间片,或者正在使用CPU执行代码。在多任务操作系统中,进程可能会频繁地在运行状态和其他状态之间切换,这是由操作系统的调度策略决定的。

  浅度睡眠状态-S

        当进程在等待某些条件满足时,它会进入浅度睡眠状态。这通常发生在进程等待外部事件(如I/O操作完成、网络数据到达、信号量变为可用等)。进程在浅度睡眠状态下可以被信号唤醒,一旦等待的条件满足,进程就会回到运行队列中等待CPU调度。

  深度睡眠状态-D

        进程处于深度睡眠状态时,它正在等待某种硬件资源的完成,最常见的是I/O操作。与浅度睡眠不同,处于深度睡眠状态的进程无法被信号唤醒,必须等到硬件操作完成才能重新调度。这种状态通常是因为进程调用了read()write()select(), 或其他系统调用而触发的。

  暂停状态-T

        暂停状态表示进程已被暂停,通常是通过接收到SIGSTOP、SIGTSTP等信号导致的。在暂停状态下,进程不会接收任何输入输出,也不会执行任何指令。它需要接收到SIGCONT信号才能解除暂停状态,重新开始执行。

  僵尸状态-Z

        当一个子进程结束但父进程没有通过wait()waitpid()调用来回收子进程资源时,子进程会变成僵尸状态。僵尸进程只占用非常小的资源,主要是内核中的少量数据结构。尽管如此,大量的僵尸进程可能会导致内存泄漏和资源浪费,因为它们占据着进程表中的条目。

  死亡状态-X

        虽然在技术上Linux内核没有正式的“X”状态,但术语“死亡状态”有时用来描述一个进程在终止后但尚未被父进程清理的状态。一旦父进程通过wait()waitpid()调用回收了子进程的资源,这个子进程的信息就会被内核释放,从而真正从系统中消失。

僵尸进程

        前面说到,一个进程若是正在等待其退出信息被读取,那么我们称该进程处于僵尸状态。而处于僵尸状态的进程,我们就称之为僵尸进程。

        例如,对于以下代码,fork函数创建的子进程在打印5次信息后会退出,而父进程会一直打印信息。也就是说,子进程退出了,父进程还在运行,但父进程没有读取子进程的退出信息,那么此时子进程就进入了僵尸状态。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{printf("I am running...\n");pid_t id = fork();if(id == 0){ //childint count = 5;while(count){printf("I am child...PID:%d, PPID:%d, count:%d\n", getpid(), getppid(), count);sleep(1);count--;}printf("child quit...\n");exit(1);}else if(id > 0){ //fatherwhile(1){printf("I am father...PID:%d, PPID:%d\n", getpid(), getppid());sleep(1);}}else{ //fork error}return 0;
} 

        运行该代码后,我们可以通过以下监控脚本,每隔一秒对该进程的信息进行检测。 

russleo@VM-0-2-ubuntu:~/7_23/proc$ while :; do ps axj | head -1 && ps axj | grep proc | grep -v grep;echo "######################";sleep 1;done

        检测后即可发现,当子进程退出后,子进程的状态就变成了僵尸状态。 

  僵尸进程的危害

  • 僵尸进程的退出状态必须一直维持下去,因为它要告诉其父进程相应的退出信息。可是父进程一直不读取,那么子进程也就一直处于僵尸状态。
  • 僵尸进程的退出信息被保存在task_struct(PCB)中,僵尸状态一直不退出,那么PCB就一直需要进行维护。
  • 若是一个父进程创建了很多子进程,但都不进行回收,那么就会造成资源浪费,因为数据结构对象本身就要占用内存。
  • 僵尸进程申请的资源无法进行回收,那么僵尸进程越多,实际可用的资源就越少,也就是说,僵尸进程会导致内存泄漏。

孤儿进程

        在Linux当中的进程关系大多数是父子关系,若子进程先退出而父进程没有对子进程的退出信息进行读取,那么我们称该进程为僵尸进程。但若是父进程先退出,那么将来子进程进入僵尸状态时就没有父进程对其进行处理,此时该子进程就称之为孤儿进程。
若是一直不处理孤儿进程的退出信息,那么孤儿进程就会一直占用资源,此时就会造成内存泄漏。因此,当出现孤儿进程的时候,孤儿进程会被1号init进程领养,此后当孤儿进程进入僵尸状态时就由int进程进行处理回收。

        例如,对于以下代码,fork函数创建的子进程会一直打印信息,而父进程在打印5次信息后会退出,此时该子进程就变成了孤儿进程。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main()
{printf("I am running...\n");pid_t id = fork();if(id == 0){ //childint count = 5;while(1){printf("I am child...PID:%d, PPID:%d\n", getpid(), getppid(), count);sleep(1);}}else if(id > 0){ //fatherint count = 5;while(count){printf("I am father...PID:%d, PPID:%d, count:%d\n", getpid(), getppid(), count);sleep(1);count--;}printf("father quit...\n");exit(0);}else{ //fork error}return 0;
} 

        观察代码运行结果,在父进程未退出时,子进程的PPID就是父进程的PID,而当父进程退出后,子进程的PPID就变成了1,即子进程被1号进程领养了。 

 

进程优先级

  基本概念

什么是优先级?
        优先级实际上就是获取某种资源的先后顺序,而进程优先级实际上就是进程获取CPU资源分配的先后顺序,就是指进程的优先权(priority),优先权高的进程有优先执行的权力。

优先级存在的原因?
        优先级存在的主要原因就是资源是有限的,而存在进程优先级的主要原因就是CPU资源是有限的,一个CPU一次只能跑一个进程,而进程是可以有多个的,所以需要存在进程优先级,来确定进程获取CPU资源的先后顺序。 

  查看系统进程

        在Linux或者Unix操作系统中,用ps -l命令会类似输出以下几个内容:

列出的信息当中有几个重要的信息,如下:

  • UID:代表执行者的身份。
  • PID:代表这个进程的代号。
  • PPID:代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号。
  • PRI:代表这个进程可被执行的优先级,其值越小越早被执行。
  • NI:代表这个进程的nice值。

  PRI与NI

  • PRI代表进程的优先级(priority),通俗点说就是进程被CPU执行的先后顺序,该值越小进程的优先级别越高。
  • NI代表的是nice值,其表示进程可被执行的优先级的修正数值。
  • PRI值越小越快被执行,当加入nice值后,将会使得PRI变为:PRI(new) = PRI(old) + NI。
  • 若NI值为负值,那么该进程的PRI将变小,即其优先级会变高。
  • 调整进程优先级,在Linux下,就是调整进程的nice值。
  • NI的取值范围是-20至19,一共40个级别。

注意: 在Linux操作系统当中,PRI(old)默认为80,即PRI = 80 + NI。

  查看进程优先级信息

        当我们创建一个进程后,我们可以使用ps -al命令查看该进程优先级的信息。

注意: 在Linux操作系统中,初始进程一般优先级PRI默认为80,NI默认为0。 

  通过top命令更改进程的nice值

    top是一个实时的进程监测工具,它提供了交互式界面来查看和控制运行中的进程。你可以使用top命令来改变一个或多个进程的nice值。

步骤:
  1. 启动top命令:在终端中输入top并按回车键。

  2. 选择进程:在top界面中,你会看到一个动态更新的进程列表。使用键盘上的上下箭头键选择你想要更改nice值的进程。

  3. 更改nice值:当你选中一个进程后,按r键。这会提示你输入一个新的nice值。输入一个整数(负数表示更高的优先级,正数表示更低的优先级),然后按回车键。

  4. 确认更改:更改会立即生效,你可以在top的进程列表中看到nice值的变化。

示例:

假设你想降低PID为1234的进程的优先级,使其调度得更少:

  1. 启动top
  2. 使用上下箭头找到PID为1234的进程。
  3. r键。
  4. 输入一个较高的数字,如19,然后按回车键。

  通过renice命令更改进程的nice值

        renice是一个非交互式的命令,用于更改一个或多个进程的nice值,适用于脚本和自动化场景。

命令语法:
renice [选项] 新的nice值 [进程ID列表]

其中,新的nice值是-20至19之间的整数,进程ID列表是一个或多个进程ID,可以是单个PID或PID范围。

示例:

1、如果你想提高PID为1234的进程的优先级,使它调度得更多,可以使用以下命令:

renice -n -5 1234

这会将PID为1234的进程的nice值减少5,即提高其优先级。

2、如果你想同时更改多个进程的nice值,可以使用逗号分隔的PID列表或PID范围:

renice -n 5 1234,5678,9012-9020

这会将PID为1234、5678以及9012到9020的所有进程的nice值增加5,即降低它们的优先级。

注意:请确保在使用renice时拥有足够的权限,因为通常需要root权限才能更改其他用户的进程的nice值。 

  四个重要概念

  • 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便有了优先级。
  • 独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰。
  • 并行: 多个进程在多个CPU下分别同时进行运行,这称之为并行。
  • 并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发。

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

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

相关文章

uni-app:踩坑路---关于使用了transform导致fixed定位不生效的问题

前言&#xff1a; 继续记录&#xff0c;在上篇文章中&#xff0c;弹出框遮罩层在ios上没有正确的铺盖全屏&#xff0c;是因为机型的原因&#xff0c;也和我们的代码结构有相关的问题。今天再来展示另外一个奇葩的问题。 这次我使用了在本篇博客中的弹出框组件CustomDialog.vue…

《昇思25天学习打卡营第19天|基于MobileNetv2的垃圾分类》

基于MobileNetv2的垃圾分类 本文档主要介绍垃圾分类代码开发的方法。通过读取本地图像数据作为输入&#xff0c;对图像中的垃圾物体进行检测&#xff0c;并且将检测结果图片保存到文件中。 1、实验目的 了解熟悉垃圾分类应用代码的编写&#xff08;Python语言&#xff09;&a…

【C++】:AVL树的深度解析及其实现

目录 前言一&#xff0c;AVL树的概念二&#xff0c;AVL树节点的定义三&#xff0c;AVL树的插入3.1 第一步3.2 第二步 四&#xff0c;AVL树的旋转4.1 右单旋4.2 左单旋4.3 右左双旋4.4 左右双旋4.5 插入代码的完整实现4.6 旋转总结 五&#xff0c;AVL树的验证六&#xff0c;实现…

插入和选择排序

1.1直接插入排序 void InsertSort(int* a, int n) {for (int i 1; i < n - 1; i) {//i的范围要注意的&#xff0c;防止指针越界int end i;int tmp a[end 1];while (end>0) {if (tmp< a[end]) {a[end 1] a[end];//小于就挪动&#xff0c;虽然会覆盖后面空间的值…

【Linux】通过分配虚拟内存的方式来解决因内存不够而导致部署的项目自动挂掉

多个 jar 包项目部署在同一台服务器上&#xff0c;当服务器配置低&#xff0c;内存不足时&#xff0c;有可能出现 nohup java -jar 启动的进程就莫名其妙挂掉的问题。 解决方式&#xff1a; 第一种方法&#xff1a;进行JVM调优可以改善这种情况&#xff0c;但是项目太多&…

【Android】安卓四大组件之广播知识总结

文章目录 动态注册使用BroadcastReceiver监听Intent广播注册Broadcast Receiver 静态注册自定义广播标准广播发送广播定义广播接收器注册广播接收器 有序广播修改发送方法定义第二个广播接收器注册广播接收器广播截断 使用本地广播实践-强制下线使用ActivityCollector管理所有活…

sql注入 mysql 执行命令 sql注入以及解决的办法

我们以前很可能听过一个词语叫做SQL注入攻击&#xff0c;其是威胁我们系统安全的最危险的因素之一&#xff0c;那么到底什么是SQL注入攻击呢&#xff1f;这里我会用一个最经典最简单的例子来跟大家解释一下&#xff1a; 众所周知&#xff0c;我们的sql语句都是有逻辑的&#xf…

STM32之九:ADC模数转换器

目录 1. 简介 2. ADC 2.1 逐次逼近型寄存器SAR 2.2 ADC转换时间 3 ADC框图 3.1 8 bit ADC0809芯片内部框图 3.2 ADC框图 3.2.1 注入通道和规则通道 3.2.2 单次/连续转换模式 3.2.3 扫描模式 3.2.4 外部触发转换 3.2.5 数据对齐 3.2.6 模拟看门狗 4. 总结和ADC驱…

MYSQL ODBC驱动安装时的注意事项

今天想使用MYSQL的ODBC驱动连接数据库。 安装的时候遇到一个大坑&#xff0c;在这里记录一下。 window 64位的操作&#xff0c;要安装64位驱动&#xff0c;这个大家都知道了。 有以下的问题要注意区别的。 1 、windows是64位的&#xff0c;但是开发软件是32位的。 这个时候…

OpenStack Yoga版安装笔记(七)glance练习补充

1、练习场景说明 在OpenStack Yoga版安装笔记&#xff08;五&#xff09;中&#xff0c;glance已经在controller node虚拟机上安装完成&#xff0c;并且已经成功拍摄了快照。 此时&#xff0c;controller node虚机已经安装了keystone、keystone DB、glance、glance DB、OpenSta…

PCL-基于FPFH的SAC-IA结合ICP的点云配准方法

目录 一、相关方法原理1.凸包方法2.FPFH特征描述3.SAC-IA概述4.ICP概述 二、实验代码三、实验结果 一、相关方法原理 点云是在同一空间参考系下表达目标空间分布和目标表面特性的海量点集合&#xff0c;在获取物体表面每个采样点的空间坐标后&#xff0c;得到的是点的集合&…

构建智能运维系统:创新架构与效率优化

随着信息技术的迅猛发展&#xff0c;企业对于运维效率和服务质量的要求越来越高。智能运维系统的设计和实施&#xff0c;不仅能够提升系统可靠性和响应速度&#xff0c;还能有效降低成本和人力投入。本文将深入探讨智能运维系统的架构设计原则和关键技术&#xff0c;为企业在运…

数据结构重置版(概念篇)

本篇文章是对数据结构的重置&#xff0c;且只涉及概念 顺序表与链表的区别 不同点 顺序表 链表 存储空间上 物理上一定连续 逻辑上连续&#xff0c;但物理上不一定连续…

.env.local 配置本地环境变量 用于团队开发

.env.local 用途&#xff1a;.env.local 通常用于存储本地开发环境中的环境变量。这些变量可能包括敏感数据或特定于单个开发者的设置&#xff0c;不应该被提交到版本控制系统中。优先级&#xff1a;在大多数框架中&#xff0c;.env.local 文件中的变量会覆盖其他 .env 文件中…

分类模型的完整流程及Python实现

1、加载函数和数据集 import numpy as np from sklearn.datasets import load_breast_cancer from sklearn.svm import SVC from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler import matplotlib.pyplot as plt cancer…

linux系统查历史cpu使用数据(使用sar 查询cpu和网络占用最近1个月历史数据)。

一 sar 指令介绍 在 Linux 系统中&#xff0c;sar 是 System Activity Reporter 的缩写&#xff0c;是一个用于收集、报告和保存系统活动信息的工具。它是 sysstat 软件包的一部分&#xff0c;提供了丰富的系统性能数据&#xff0c;包括 CPU、内存、网络、磁盘等使用情况&am…

SQL中的LEFT JOIN、RIGHT JOIN和INNER JOIN

在SQL中&#xff0c;JOIN操作是连接两个或多个数据库表&#xff0c;并根据两个表之间的共同列&#xff08;通常是主键和外键&#xff09;返回数据的重要方法。其中&#xff0c;LEFT JOIN&#xff08;左连接&#xff09;、RIGHT JOIN&#xff08;右连接&#xff09;和INNER JOIN…

《JavaEE篇》--多线程(2)

《JavaEE篇》--多线程(1) 线程安全 线程不安全 我们先来观察一个线程不安全的案例&#xff1a; public class Demo {private static int count 0;public static void main(String[] args) throws InterruptedException {Thread t1 new Thread(() -> {//让count自增5W次…

HarmonyOS网络请求的简单用法,HttpUtil简单封装

请求网络获取数据 点击按钮发送一个post请求&#xff0c;发送一条string由于此处的返回result.data本身就是一个string&#xff0c;因此不需要转换类型 Button(请求网络).margin({ top: 10 }).fontSize(24).fontWeight(FontWeight.Bold).onClick(() > {httpRequestPost(http…

风格迁移开发记录(DCT-Net)

1.DCT-Net部署 阿里旗下的 modelscope社区&#xff0c;丰富的开源风格迁移算法模型 DCT-Net GitHub链接 git clone https://github.com/menyifang/DCT-Net.git cd DCT-Netpython run_sdk.py下载不同风格的模型如下图每个文件夹代表一种风格&#xff0c;有cartoon_bg.pb, car…