当前位置: 首页 > news >正文

Linux | 进程相关概念(进程、进程状态、进程优先级、环境变量、进程地址空间)

文章目录

  • 进程概念
    • 1、冯诺依曼体系结构
    • 2、进程
      • 2.1基本概念
      • 2.2描述进程-PCB
      • 2.3组织进程
      • 2.4查看进程
      • 2.5通过系统调用获取进程标识符
      • 2.6通过系统调用创建进程-fork初识
        • fork の 头文件与返回值
        • fork函数的调用逻辑和底层逻辑
    • 3、进程状态
      • 3.1状态
      • 3.2进程状态查看命令
        • 3.2.1 ps命令
        • 3.2.2 top命令
        • 3.2.3 htop命令
        • 3.2.4 pidof命令
        • 3.2.5pgrep命令
        • 3.2.6 /proc文件系统:
      • 3.3僵尸进程(Z状态)
      • 3.4孤儿进程
    • 4、进程优先级
      • 4.1基本概念
      • 4.2查看系统进程
        • 4.2.1 ps -l
        • 4.2.2 PRI & NI
      • 4.3用top命令更改已存在进程的nice:
    • 5、环境变量
      • 5.1常见环境变量
      • 5.2查看环境变量
      • 5.3测试PATH
        • 配置环境变量
      • 5.4代码中获取环境变量
    • 6、进程地址空间
      • 6.1程序地址空间
      • 6.2进程地址空间

进程概念

1、冯诺依曼体系结构

简单来说,计算机中是由一个个硬件构成

  • 输入单元:键盘、鼠标、写字板等
  • 中央处理器(CPU):含有运算器和控制器等
  • 输出单元:显示器,打印机等

对于冯诺依曼一些结构,有以下几点注意:

  • 存储器指的是内存
  • 不考虑缓存情况,这里的CPU能且只能对内存进行读写, 不能访问外设
  • 外设(输入设备或输出设备)要输入或者输出数据,也只能写入内存或者从内存中读取
  • 总结就是:所有设备只能直接和内存打交道

2、进程

2.1基本概念

程序的一个执行实例,正在执行的程序等。担当分配系统资源(CPU时间,内存)的实体。

2.2描述进程-PCB

进程信息被放在进程控制块(一个数据结构),叫做PCB,Linux操作系统下的PCB是task_struct

进程 = 内核数据结构(PCB) + 程序段 + 数据段

task_struct内容分类

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

2.3组织进程

可以在内核源代码里找到,所有运行系统里的进程都以task_struct链表的形式存在内核里

2.4查看进程

如:要获取PID为1的进程信息,你需要查看 /proc/1 这个文件夹。

大多数进程信息同样可以使用top和ps这些用户级工具来获取

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.5通过系统调用获取进程标识符

  • 进程id(PID)
  • 父进程id(PPID)

获取进程识别码(getpid函数与getppid函数)

  • 函数原型:pid_t getpid(void) pid_t getppid(void)

    其中返回值类型pid_t是一种有符号整型,也可以使用整形int类型变量来接收

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{printf("pid: %d\n", getpid());printf("ppid: %d\n", getppid());return 0;
}

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

  • 使用man手册运行man fork认识fork函数
  • fork有两个返回值
  • 父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)

fork の 头文件与返回值
  • 头文件:unistd.h

  • 函数原型:pid_t fork(void);

  • 父进程中,fork返回新创建子进程的进程ID

  • 子进程中,fork返回0


fork函数的调用逻辑和底层逻辑

在上文介绍PCB的时候有提到过,进程由内核数据结构和代码、数据两部分组成。因此每个进程都会有自己的PCB即task_struct结构体。当调用了fork函数后,系统创建子进程,即创建一个属于子进程的task_struct,将父进程的大部分属性拷贝过去(不在内的如pid、ppid),由于父子进程属于同一个程序,他们的代码是共用的,但是两个进程同时访问一个变量的时候会出现冲突问题,因此子进程会将它将要访问的数据做一份额外的拷贝,也就是子进程访问拷贝出来的数据,然后父子进程就有了属于各自的数据,对变量的操作也是独立的。

fork函数创建子进程过程

  • 创建子进程PCB
  • 填充PCB对应的内容属性
  • 让子进程和赴京城指向同样的代码
  • 父子进程都是有独立的task_struct,已经可以被CPU调度运行了

问:为什么fork函数调用完后会返回两个值,这和寻常的函数不是不一样么?

在fork函数中,创建子进程的步骤完成后,在return返回之前,父子进程已经可以被CPU调度运行了,也就是说,在return前fork函数执行了父子两个进程,return是作为父子进程的共有程序,他们都会各自返回一个值,因此整体看fork函数会返回两个值,分别属于调用fork函数中父子进程的返回值。

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{int ret = fork();printf("hello proc : %d!, ret: %d\n", getpid(), ret);sleep(1);return 0;
}
  • 由于父子进程的代码是一样的,因此如果需要使得父子进程执行不一样的代码,可以使用if加上返回值的条件限定来进行父子进程分流

    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    int main()
    {int ret = fork();if(ret < 0){perror("fork");return 1;}else if(ret == 0){ //childprintf("I am child : %d!, ret: %d\n", getpid(), ret);}else{ //fatherprintf("I am father : %d!, ret: %d\n", getpid(), ret);}return 0;
    }
    

3、进程状态

在程序运行的时候,如果遇到一个scanf等语句,进程会暂停知道输入相应的数据,才继续运行,由此可见进程需要有不同的状态(例如运行、阻塞、挂起等),不然进程无法按照预期正常执行。

3.1状态

  • R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里

  • S睡眠状态(sleeping): 可中断睡眠状态,意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠 (interruptible sleep))

  • **D磁盘休眠状态(Disk sleep):**不可中断睡眠状态,在这个状态的 进程通常会等待IO的结束。

  • T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可 以通过发送 SIGCONT 信号让进程继续运行。

  • **X死亡状态(dead):**这个状态只是一个返回状态,你不会在任务列表里看到这个状态。

  • z僵尸状态(zombie): 进程结束运行后大部分资源被回收,但进程描述符仍保留,直到父进程获取其退出状态。处于该状态的进程已死亡却占据一定系统资源,会在任务列表里显示为Z,过多僵尸进程会造成系统资源浪费。

运行队列

​ 进程需要执行的时候,会被加入到运行队列中,并由调度器对队列进行调度,在CPU中执行运行的进程,无论是在运行中的还是在运行队列中的进程都是在R运行状态。示意图如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


3.2进程状态查看命令

3.2.1 ps命令

用于查看当前系统中的进程状态。

  • 语法ps [选项]
  • 常用选项
    • -a:显示所有与终端相关的进程,包括其他用户的进程。
    • -u:以用户格式显示进程信息,包括用户名、启动时间等。
    • -x:显示所有进程,包括没有控制终端的进程。
    • -ef:显示所有进程的详细信息,包括进程ID(PID)、父进程ID(PPID)等。
    • -j: 会以作业格式显示进程信息,这种格式输出的内容比默认格式更丰富,会额外展示一些进程的上下文信息,常见的有:
      • PPID:父进程 ID,用于表明该进程是由哪个进程创建的。
      • PGID:进程组 ID,它将相关的进程组织在一起形成一个进程组。
      • SID:会话 ID,代表进程所属的会话,有助于对进程进行更宏观的管理和分类。

例如,想要查看常用的指令可以使用:ps ajx | head -1; ps axj | grep test1来查看test1可执行程序的进程相关信息,如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当执行 ps axj | grep test1 时,你可能会看到输出结果中包含一个 grep 进程,这是因为 grep 命令本身也是一个进程,并且它在执行搜索时,ps axj 的输出中也包含了 grep test1 这个命令行字符串,所以 grep 会把自身这个进程也匹配出来并显示在结果中。

3.2.2 top命令

动态地显示系统中各个进程的资源占用情况,如CPU使用率、内存使用率等。

  • 语法top [选项]
  • 常用选项
    • -d:指定更新间隔时间,单位为秒。例如,top -d 5表示每5秒更新一次显示内容。
    • -b:以批处理模式运行,可用于将输出重定向到文件。
    • -n:指定显示的次数。例如,top -n 3表示只显示3次更新后的结果。

top命令的交互界面中,还可以使用一些按键进行操作,如按M键可以按照内存使用量对进程进行排序,按P键可以按照CPU使用率进行排序等。

3.2.3 htop命令

top命令的增强版,提供了更友好的交互式界面,支持鼠标操作,并且可以更直观地显示进程树等信息。

  • 语法htop

直接在终端输入htop即可启动该命令,使用方法与top类似,但界面更加丰富和易于操作。

3.2.4 pidof命令

用于查找指定名称的进程的PID。

  • 语法pidof [进程名称]

例如,要查找名为nginx的进程的PID,可以使用命令:pidof nginx

3.2.5pgrep命令

根据进程名称或其他条件查找进程的PID。

  • 语法pgrep [选项] [进程名称]
  • 常用选项
    • -l:显示进程名称和PID。
    • -u:指定用户,只查找该用户的进程。

例如,要查找用户ubuntu下名为python的进程的PID,并显示进程名称和PID,可以使用命令:pgrep -lu ubuntu python

  • ps -l 列出与本次登录有关的进程信息;
  • ps -aux 查询内存中进程信息;
  • ps -aux | grep + 程序名字 查询该程序进程的详细信息;
  • top 查看内存中进程的动态信息;
  • kill -9 + pid 杀死进程。

举例如下图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其中,在使用ps -l命令时,注意到几个信息,有下:

  • UID : 代表执行者的身份
  • PID : 代表这个进程的代号
  • **PPID :**代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
  • **PRI :**代表这个进程可被执行的优先级,其值越小越早被执行
  • **NI :**代表这个进程的nice值
3.2.6 /proc文件系统:
  • Linux的 /proc 文件系统包含了大量关于系统和进程的信息。

    • 每个进程都有一个以其PID命名的目录,如 /proc/1234,其中包含了该进程的详细信息。

    • 可以查看 /proc/[PID]/status 文件来获取进程的状态信息。

例如执行ls /proc/45311 -dl

/proc/45311 是目标路径,其中 /proc 是系统中用于反映进程运行状态的虚拟文件系统,45311 代表特定进程的 ID,此路径指向该进程对应的目录;-dl 是选项组合,-d 使 ls 仅列出目录本身而非其内部内容,-lls 以长格式输出详细信息

3.3僵尸进程(Z状态)

  • 僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用) 没有读取到子进程退出的返回代码时就会产生僵死(尸)进程
  • 僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码
  • 所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态

下面是一个僵尸进程例子:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main(){pid_t ret = fork();if(ret == 0){ printf("child process exit\n");exit(0);}   else{while(1){}   }   return 0;

可以复制一个当前会话便于观察进程信息,下图一为上面代码运行效果,下图二为运行中的进程信息,可以看到由于子进程代码中有exit(0)而提前退出,而父进程一直等待子进程的反馈未果,因而子进程处于z状态。想要结束程序可以使用Ctrl + c 退出或使用kill命令。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

进程一般退出的时候,如果父进程没有主动回收子进程信息,子进程会一直让自己处于Z状态,进程的相关资源尤其是task_struct结构体不能被释放

僵尸进程的危害

  • 进程的退出状态必须被维持下去。父进程如果一直不读取,那子进程就一直处于Z状态
  • 维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话 说,Z状态一直不退出,PCB一直都要维护
  • 那一个父进程创建了很多子进程,就是不回收,会造成内存资源的浪费。因为数据结构 对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间的,不会受会造成内存泄漏

3.4孤儿进程

  • 父进程如果提前退出,那么子进程后退出,进入Z之后,那该如何处理呢?
  • 父进程先退出,子进程就称之为“孤儿进程”
  • 孤儿进程被1号systemd进程”领养“,当然要有systemd进程回收。

下面是一个孤儿进程的例子。

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main(){pid_t ret = fork();if(ret == 0){ for(int i=0;i<60;i++){  printf("chile process %d \n",getpid());sleep(1);}   }   else{for(int i=0;i<8;i++){printf("father process %d\n",getpid());sleep(1);}   exit(0);}   return 0;
}

可以看到父进程提前退出,子进程继续执行,如果观察进程信息会发现子进程在父进程提前退出后它的PPID变成了1。使用ps ajx | grep systemd会发现PID是1,即1号进程就是操作系统本身。我们把这种子进程称为孤儿进程。

为什么孤儿进程的PPID会变成1?

因为子进程将来需要被释放,原来的父进程提前退出,因此子进程被系统进程”领养“,在结束后进程后释放掉子进程。

4、进程优先级

4.1基本概念

  • cpu资源分配的先后顺序,就是进程的优先权
  • 优先权高的进程有优先执行权,配置进程优先权对多任务环境的linux很有用,可以改善系统性能
  • 还可以把进程运行到指定的CPU上,把不重要的进程安排到某个CPU,可以大大改善系统整体性能

4.2查看系统进程

4.2.1 ps -l

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在使用ps -l命令时,注意到几个信息,有下:

  • UID : 代表执行者的身份
  • PID : 代表这个进程的代号
  • **PPID :**代表这个进程是由哪个进程发展衍生而来的,即父进程的代号
  • PRI :代表这个进程可被执行的优先级,其值越小越早被执行
  • **NI :**代表这个进程的nice值,nice值:进程优先级的修正数据(可以用来改)
4.2.2 PRI & NI
  • PRI,即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高
  • NI就是我们所要说的nice值了,其表示进程可被执行的优先级的修正数值
  • PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice
  • 这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行
  • 所以,调整进程优先级,在Linux下,就是调整进程nice值
  • nice其取值范围是**-20至19**,一共40个级别。

  • 需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进 程的优先级变化。
  • 可以理解nice值是进程优先级的修正修正数据

4.3用top命令更改已存在进程的nice:

  • top
  • 进入top后按 “r“ -> 输入进程PID -> 输入nice值

5、环境变量

5.1常见环境变量

  • PATH : 指定命令的搜索路径
  • HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
  • SHELL : 当前Shell,它的值通常是/bin/bash。

5.2查看环境变量

环境变量相关命令

  • echo $NAME 显示某个环境变量的值,其中NAME是环境变量名称
  • export: 设置一个新的环境变量
  • env: 显示所有环境变量
  • unset: 清除环境变量
  • set: 显示本地定义的shell变量和环境变量

5.3测试PATH

  • 举一个简单的例子
#include<stdio.h>int main()
{int i;for(i=0;i<5;i++){printf("I am a process\n");}   return 0;
}

我们将他编译为叫process的可执行程序,当需要执行这个程序的时候我们应该使用./process来执行,直接输入process会显示”command not found“。但是在执行命令的时候比如touch命令、ls命令等,我们只需要输入命令名字即可,如果我们想让process这个程序像命令一样执行,即输入process就能执行,那么可以将程序所在路径加入到环境变量PATH当中

配置环境变量
  • PATH=$PATH:/root/workspace/Linux 将当前程序所在的路径加入到环境变量PATH当中
  • PATH=/root/workspace/Linux 将当前程序所在的路径覆盖至环境变量PATH当中,相当于把PATH当中全部覆盖掉,然后ls等指令就会失效了。

执行完后,我们就可以直接输入process来执行程序,不需要带上路径了,甚至用mv将process改名后也能正常运行。使用which process也能找到~/root/workspace/Linux。

5.4代码中获取环境变量

getnev函数

  • 函数声明:

    char *getenv(const char *name) 其中name是需要获取的环境变量名

  • 使用举例:

    #include<stdio.h>
    #include<stdlib.h>int main()
    {printf("PATH:%s\n",getenv("PATH"));return 0;
    }

6、进程地址空间

6.1程序地址空间

地址空间一共有如下的几个区域,从下到上地址逐渐增加,其中栈区的空间是从上往下使用,即从高地址往低地址增长;堆区的空间是从下往上使用,即从低地址往高地址增长需要注意的是,在不同位操作系统下或者不同编译器下,内存的分配规则都可能是不同的,这里以linux为例,也是最经典的一种。

我们平时敲代码使用程序地址空间的时候,当我们定义一个局部变量,它的空间就是在栈区上开辟的,有临时性;当我们使用malloc申请空间的时候,是在堆区开辟的空间;当我们定义一个全局变量的时候,它的空间就是在全局变量中开辟的,其中也分为未初始化全局变量和已初始化全局变量。在32位系统下的寻址空间是4GB

为了直观地体现出地址分配的规则,我们使用一些例子来做演示:

#include<stdio.h>
#include<stdlib.h>int val1 = 10;
int val2;int main() {//以下均为存储在各区地址空间中的实例printf("代码区:            %p\n", main);const char* str = "helllo linux";printf("字符常量区:         %p\n", str);printf("已初始化全局变量区:  %p\n", &val1);printf("未初始化全局变量区:  %p\n", &val2);char* a = (char*)malloc(sizeof(char));printf("堆区:             %p\n", a);printf("栈区:             %p\n", &str);return 0;
}

运行结果如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

通过运行结果会发现打印出来的地址从代码区到栈区依次递增。

6.2进程地址空间

当我们使用fork()函数生成一个子进程的时候,子进程会对将要访问的父进程的内容进行写时拷贝,但是会发现子进程和父进程对于同一个全局变量进行访问更改等操作的时候,这个变量的地址是不变的,也就是说同一个地址可能会有两个值,因为这里的地址并不是物理地址,而是虚拟地址(我们平时写程序用到的地址相关的内容一般都是虚拟地址)。如果是物理地址,这是绝对不可能的,可以配合下面案例理解:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int val = 0;
int main()
{pid_t id = fork();if(id < 0){perror("fork");return 0;}else if(id == 0){ //child,子进程肯定先跑完,也就是子进程先修改,完成之后,父进程再读取val=100;printf("child: %d : %p\n", val, &val);}else{ //parentsleep(3);printf("parent: %d : %p\n", val, &val);}sleep(1);return 0;
}

运行结果如图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

会发现前文所说的现象,同一个变量,子进程对其将要访问的变量进行写时拷贝,但是父子进程中的val确是同一个地址,因此这里的地址是虚拟地址而非物理地址。他们地址上的逻辑应该对应下图(简化):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 当父进程创建出来,系统创建了父进程的PCB和父进程的进程地址空间,PCB指向进程地址空间
  • 这里创建的进程地址空间是虚拟地址,虚拟地址和物理内存是通过页表来映射的
  • 当访问某个地址时,页表通过映射关系,查找到物理地址,并读取存在当中的数据
  • 当父进程创建子进程的时候,系统也根据父进程为模板创建子进程对应的PCB和进程地址空间
  • 由于子进程时以父进程为模板创建的,因此他们页表是一样的,因此子进程和父进程能够共享代码
  • 对于同一个全局变量,当子进程需要对其进行写入等操作时,由于父子进程的虚拟地址对应同一块物理地址,为保证独立性,系统会在物理内存中额外开辟一块空间
  • 至此,父子进程各自页表中对于此全局变量的虚拟地址是相同的,但是对应的物理地址是不同的。

相关文章:

Linux | 进程相关概念(进程、进程状态、进程优先级、环境变量、进程地址空间)

文章目录 进程概念1、冯诺依曼体系结构2、进程2.1基本概念2.2描述进程-PCB2.3组织进程2.4查看进程2.5通过系统调用获取进程标识符2.6通过系统调用创建进程-fork初识fork の 头文件与返回值fork函数的调用逻辑和底层逻辑 3、进程状态3.1状态3.2进程状态查看命令3.2.1 ps命令3.2.…...

站群服务器和普通服务器有哪些不同之处?

站群服务器是一个集中管理工具&#xff0c;可以允许网站管理员同时管理多个网站&#xff0c;但是不要管理员登录每一个网站的后台&#xff0c;在站群模式下&#xff0c;网站管理员通过一个或者多个服务器来托管大量的子站点&#xff0c;可以支持大规模网站的集中管理和优化。 普…...

百度千帆平台对接DeepSeek官方文档

目录 第一步&#xff1a;注册账号&#xff0c;开通千帆服务 第二步&#xff1a;创建应用&#xff0c;获取调用秘钥 第三步&#xff1a;调用模型&#xff0c;开启AI对话 方式一&#xff1a;通过API直接调用 方式二&#xff1a;使用SDK快速调用 方式三&#xff1a;在千帆大模…...

DeepSeek帮助解决Oracle死锁问题

最近在生产上遇到一个死锁问题&#xff0c;Oracle 抛出了 ORA-000060 异常。 业务场景&#xff1a;程序按行读取一个上游系统送的文件数据&#xff08;大概有几万行&#xff09;&#xff0c;读取到数据后&#xff0c;每 500 行分配给一个线程去批量更新数据库&#xff08;使用…...

MySQL无法连接到本地localhost的解决办法2024.11.8

问题描述&#xff1a;我的MySQL可以远程连接服务器&#xff0c;但无法连接自己的localhost。 错误提示&#xff1a; 2003 - Cant connet to MySQL server on localhost(10061 "Unknown error")查找问题原因&#xff1a; 1. 检查环境变量是否正确&#xff1a;发现没…...

Nginx之rewrite重写功能

目录 一、rewrite概述 1、rewrite功能 2、跳转场景 二、标准配置指令 1、rewrite日志记录指令 2、未初始化变量告警日志记录指令 3、rewrite 指令 3.1 正则表达式 三、rewrite模块使用实例 1.基于域名的跳转 2.基于客户端 IP 访问跳转 3.?基于旧域名跳转到新域名后…...

Selenium WebDriver自动化测试(扩展篇)--Jenkins持续集成

文章目录 一、引言二、Jenkins简介三、安装部署Jenkins安装部署四、集成Git与Maven安装必要的插件配置Git配置Maven五、创建Job创建自由风格的项目配置源码管理配置构建触发器配置构建环境配置构建步骤配置Post-build Actions六、触发构建示例:GitHub Webhook触发构建七、封装…...

MyBatis拦截器终极指南:从原理到企业级实战

在本篇文章中&#xff0c;我们将深入了解如何编写一个 MyBatis 拦截器&#xff0c;并通过一个示例来展示如何在执行数据库操作&#xff08;如插入或更新&#xff09;时&#xff0c;自动填充某些字段&#xff08;例如 createdBy 和 updatedBy&#xff09;信息。本文将详细讲解拦…...

DeepSeek4j 已开源,支持思维链,自定义参数,Spring Boot Starter 轻松集成,快速入门!建议收藏

DeepSeek4j Spring Boot Starter 快速入门 简介 DeepSeek4j 是一个专为 Spring Boot 设计的 AI 能力集成启动器&#xff0c;可快速接入 DeepSeek 大模型服务。通过简洁的配置和易用的 API&#xff0c;开发者可轻松实现对话交互功能。 环境要求 JDK 8Spring Boot 2.7Maven/Gr…...

linux 板子的wifi模块连上路由器后,用udhcpc给板子wifi分配ip,udhcpc获取到ip,但没有写入wlan0网卡上

linux 板子的wifi模块连上路由器后&#xff0c;用udhcpc给板子wifi分配ip&#xff0c;udhcpc获取到ip,但没有写入wlan0网卡上 这里的问题是 /usr/share/udhcpc/default.script脚本有问题 用下面正确脚本&#xff0c;即可写进去 #!/bin/sh# udhcpc script for busybox # Copyr…...

【工业安全】-CVE-2022-35555- Tenda W6路由器 命令注入漏洞

文章目录 1.漏洞描述 2.环境搭建 3.漏洞复现 4.漏洞分析 4.1&#xff1a;代码分析  4.2&#xff1a;流量分析 5.poc代码&#xff1a; 1.漏洞描述 漏洞编号&#xff1a;CVE-2022-35555 漏洞名称&#xff1a;Tenda W6 命令注入 威胁等级&#xff1a;高危 漏洞详情&#xff1…...

twisted实现MMORPG 游戏数据库操作封装设计与实现

在设计 MMORPG&#xff08;大规模多人在线角色扮演游戏&#xff09;时&#xff0c;数据库系统是游戏架构中至关重要的一部分。数据库不仅承担了游戏中各种数据&#xff08;如玩家数据、物品数据、游戏世界状态等&#xff09;的存储和管理任务&#xff0c;还必须高效地支持并发访…...

【MySQL】基础篇

1. MySQL中的NULL值是怎么存放的&#xff1f; MySQL的compact行格式中会用【NULL值列表】来标记值为NULL的列&#xff0c;NULL值不会存储在行格式中的真实数据部分。 NULL值列表会占用1字节空间&#xff0c;当表中所有字段都被定义成NOT NULL&#xff0c;行格式中就不会有NULL值…...

【自学笔记】机器学习基础知识点总览-持续更新

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 机器学习重点知识点总览一、机器学习基础概念二、机器学习理论基础三、机器学习算法1. 监督学习2. 无监督学习3. 强化学习 四、机器学习处理流程五、机器学习常见问…...

记录阿里云CDN配置

网站接入CDN全流程&#xff0c;共4步&#xff01;-阿里云开发者社区 1、开通阿里云CDN服务 2、添加加速域名 3、验证域名归属权 4、域名添加CDN生成的CNAME解析 按照官网描述增加。细节点&#xff1a; 1. 域名和泛域名区别 2.开启https,要用nginx的证书&#xff0c;和项…...

同为科技智能PDU助力Deepseek人工智能和数据交互的快速发展

1 2025开年&#xff0c;人工智能领域迎来了一场前所未有的变革。Deepseek成为代表“东方力量”的开年王炸&#xff0c;不仅在国内掀起了技术热潮&#xff0c;并且在全球范围内引起了高度关注。Deepseek以颠覆性技术突破和现象级应用场景席卷全球&#xff0c;这不仅重塑了产业格…...

聚铭网络入围2025年度江苏省政府采购信息安全设备协议供货名单

近日&#xff0c;2025年度江苏省党政机关、事业单位及团体组织信息安全设备框架协议采购项目入围结果公布。聚铭网络凭借自身专业实力和技术优势脱颖而出&#xff0c;成功入围22个分包。 此次采购项目是江苏省政府采购领域级别最高、覆盖面最广的项目之一。从资格评选到后期材料…...

【Linux】--- 基础开发工具之yum/apt、vim、gcc/g++的使用

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; Linux网络编程 本篇博客我们来认识一下Linux中的一些基础开发工具 --- yum,vim,gcc/g。 &#x1f3e0; yum &#x1f3b8; 什么是yum 当用户想下载软…...

leetcode 297. 二叉树的序列化与反序列化

题目如下 我们常常说单独先序遍历不能完整的表示一棵树是有前提条件的。 为什么&#xff1f;先序遍历是按 根节点 左子树 右子树的方向遍历树且遇到空子树直接返回&#xff0c;这样会造成我们并不知道某个节点的左右子树存在与否&#xff0c;故我们无法确定树的形状。但是如果…...

OpenAI 放王炸,将发布整合多项技术的 GPT-5,并免费无限使用,该模型有哪些技术亮点

对于 ChatGPT 的免费用户&#xff0c;将可以无限制地访问 GPT-5&#xff0c;但仅限于标准的智能级别。该级别会设定滥用限制&#xff0c;以防止不当使用(意思就是你得付费嘛)。 OpenAI CEO Sam Altman 今天在 X 上透露了 GPT-4.5 和 GPT-5 的最新发展计划。 OpenAI 将发布代…...

Ubuntu22.04 使用useradd 创建用户时,没有创建家目录时,如何手动创建家目录

测试案例&#xff1a; 使用useradd不加参数创建test目录 如下可以看出使用 useradd 创建用户的时候默认不会创建家目录 rootlocal:~# useradd test rootlocal:~# id test uid1001(test) gid1001(test) groups1001(test) rootlocal:~# cat /etc/passwd | grep test test:x:1001:…...

浅聊Docker使用、部署

在Java面试中&#xff0c;当被问到关于Docker中间件的使用、部署及在实际项目中的考虑时&#xff0c;可以按照以下结构和内容来详细回答&#xff1a; 一、Docker中间件的使用 1. Docker是什么&#xff1f; Docker是一个开源平台&#xff0c;允许开发者将应用程序及其依赖项打…...

Java面试第一山!《集合》!

一、引言 在 Java 编程的世界里&#xff0c;数据的存储和处理是非常重要的环节。Java 集合框架就像是一个功能强大的工具箱&#xff0c;为我们提供了各种各样的数据结构来高效地存储和操作数据。今天&#xff0c;跟随小编一起来深入了解 Java 集合框架&#xff0c;这不仅有助于…...

力扣-二叉树-257 二叉树的所有路径

思路 除去根节点&#xff0c;每一层添加->val&#xff0c;然后使用前序遍历的顺序 代码 class Solution { public:vector<string> res;void getTreePaths(string s, TreeNode* root){s "->";s to_string(root->val);if(root->left nullptr &…...

异构计算架构助力智能座舱实现高效低耗体验

摘要: 随着智能汽车的飞速发展,智能座舱作为人车交互的核心区域,对算力、功耗及延迟等性能指标提出了严苛要求。异构计算架构凭借在硬件、软件与系统层面的深度优化,能显著提升智能座舱的算力利用率,降低功耗与延迟,为用户打造高效、低能耗的智能座舱体验。本文深入剖析…...

【vscode】VScode Remote SSH配置

VScode使用remote ssh 到服务器上的Docker容器中 1. 配置远程服务器docker容器的端口映射&#xff0c;例如将服务器的2222端口映射到container的22端口(默认) 1.1 在容器系统的sshd_config文件中配置参数 #配置文件 vim /etc/ssh/sshd_config #打开端口号 Port 221.2 建立容…...

急停信号的含义

前言&#xff1a; 大家好&#xff0c;我是上位机马工&#xff0c;硕士毕业4年年入40万&#xff0c;目前在一家自动化公司担任软件经理&#xff0c;从事C#上位机软件开发8年以上&#xff01;我们在开发C#的运动控制程序的时候&#xff0c;一个必要的步骤就是确认设备按钮的急停…...

【Azure 架构师学习笔记】- Azure Databricks (11) -- UC搭建

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (10) – UC 使用 前言 由于ADB 的更新速度很快&#xff0c;在几个月之后重新搭建ADB 时发现UC 已经更新了很多&#xff0c;为了后续做ADB 的功…...

MYSQL批量UPDATE的两种方式

工作中遇到批量更新的场景其实是比较常见的。 但是该如何正确的进行批量UPDATE&#xff0c;很多时候往往有点头大。 这里列2种可用的方式&#xff0c;供选择(请选择方式一&#xff0c;手动狗头。)。 如果使用了MyBatis增强组件MyBatisPlus 如果使用了MyBatisPlus&#xff0c;…...

百度宣布:免费!

2月13日&#xff0c;百度大模型文心一言在官网宣布&#xff0c;随着文心大模型的迭代升级和成本不断下降&#xff0c;文心一言将于4月1日起全面免费&#xff0c;所有PC端和APP端用户均可体验文心系列最新模型。 同时&#xff0c;文心一言将上线深度搜索功能&#xff0c;具备更…...

计算机毕业设计SpringBoot+Vue.js医院住院管理系统(源码+lw文档+PPT+讲解视频)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

Anaconda +Jupyter Notebook安装(2025最新版)

Anaconda安装&#xff08;2025最新版&#xff09; Anaconda简介安装1&#xff1a;下载anaconda安装包2&#xff1a; 安装anaconda3&#xff1a;配置环境变量4&#xff1a;检查是否安装成功5&#xff1a;更改镜像源6&#xff1a;更新包7&#xff1a;检查 Jupyter Notebook一.Jup…...

人工智能任务21-飞蛾火焰优化算法(MFO)在深度学习中的应用

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能任务21-飞蛾火焰优化算法(MFO)在深度学习中的应用。飞蛾火焰优化算法&#xff08;Moth-Flame Optimization, MFO&#xff09;是一种受自然界中飞蛾向光源趋近行为启发的新型群体智能优化算法。在自然界中&a…...

渗透测试工具:SQLmap安装教程及使用

在渗透测试的世界里&#xff0c;SQL注入攻击无疑是最常见且最具威胁的安全漏洞之一。幸运的是&#xff0c;SQLmap 这个强大的自动化工具&#xff0c;能够帮助我们快速识别和利用这些漏洞。如果你也想了解如何用 SQLmap 进行渗透测试&#xff0c;那么这篇文章就是为你准备的&…...

【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第十四节】

ISO 14229-1:2023 UDS诊断服务测试用例全解析&#xff08;CommunicationControl_0x28服务&#xff09; 作者&#xff1a;车端域控测试工程师 更新日期&#xff1a;2025年02月14日 关键词&#xff1a;UDS协议、0x28服务、通信控制、ISO 14229-1:2023、ECU测试 一、服务功能概述…...

WEB安全--SQL注入--INTO OUTFILE

一、INTO OUTFILE 函数语法&#xff1a; SELECT column1, column2, INTO OUTFILE file_path FROM your_table WHERE your_conditions; 使用此方式在SQL注入的过程中可以&#xff1a; 1、上传shell得到数据库的后端的操作权限 2、爆出数据库的信息 二、使用该函数的条件&#…...

【C语言 】C语言 桌游开发数字竞拍(源码)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;专__注&#x1f448;&#xff1a;专注主流机器人、人工智能等相关领域的开发、测试技术。 【C语言 】C语言 桌游开发数字竞拍&#xff08;源码…...

开源赋能,智造未来:Odoo+工业物联网,解锁智能工厂新范式——以真实案例解读制造业数字化转型的降本增效密码

工业物联网的机遇与挑战&#xff1a;为什么企业需要Odoo&#xff1f; 《中国智能制造发展研究报告2023》指出&#xff0c;85%的制造企业已启动数字化转型&#xff0c;但超60%面临“数据孤岛、系统割裂、成本高企”的痛点[1]。传统ERP系统难以实时对接产线设备&#xff0c;而定…...

在分布式场景下可以使用synchronized加锁么?

首先说结论&#xff0c;在分布式系统中&#xff0c;单纯使用 Java 中的 synchronized 关键字是无法满足需求的&#xff0c;下面从 synchronized 的作用原理、在分布式场景下的局限性以及替代方案等方面详细分析。 一、synchronized 的作用原理 在 Java 中&#xff0c;synchron…...

DeepSeek从入门到精通:提示词设计的系统化指南

目录 引言&#xff1a;AIGC时代的核心竞争力 第一部分 基础篇&#xff1a;提示词的本质与核心结构 1.1 什么是提示词&#xff1f; 1.2 提示词的黄金三角结构 第二部分 类型篇&#xff1a;提示词的六大范式 2.1 提示语的本质特征 2.2 提示语的类型 2.2.1 指令型提示词 …...

C# 运算符

总目录 前言 在C#中&#xff0c;运算符是用于执行特定操作的符号。它们可以用于处理变量、常量或其他表达式。C# 提供了丰富的运算符集合&#xff0c;用于执行各种操作&#xff0c;如算术运算、逻辑判断、位操作等。了解这些运算符及其使用方式对于编写高效且功能强大的C#程序…...

duckdb导出Excel和导出CSV速度测试

运行duckdb数据库 D:>duckdb v1.2.0 5f5512b827 Enter “.help” for usage hints. Connected to a transient in-memory database. Use “.open FILENAME” to reopen on a persistent database. 生成模拟数据&#xff0c;10个列&#xff0c;100万行数据&#xff1b; --…...

pt->onnx->rknn(量化) step by step FAQ

文档修订中... 1.pt->onnx 这个转换是在yolov11的docker环境做的转换。非常简单。 #!/usr/bin/env python3 # -*- coding: utf-8 -*- # 获取当前脚本文件所在目录的父目录&#xff0c;并构建相对路径 import os import sys current_dir os.path.dirname(os.path.abspath…...

Apollo 9.0 速度动态规划决策算法 – path time heuristic optimizer

文章目录 1. 动态规划2. 采样3. 代价函数3.1 障碍物代价3.2 距离终点代价3.3 速度代价3.4 加速度代价3.5 jerk代价 4. 回溯 这一章将来讲解速度决策算法&#xff0c;也就是SPEED_HEURISTIC_OPTIMIZER task里面的内容。Apollo 9.0使用动态规划算法进行速度决策&#xff0c;从类名…...

利用AI智能体创建云端文档知识库并集成第三方数据源(上)

许多开发者在管理和集成多种云端的数据源时经常面对各种各样的困难&#xff0c;所以希望能够构建一个聊天机器人来协调这些数据源&#xff0c;针对业务问题并提供全面的答案。本文介绍了一种解决方案&#xff0c;帮助大家开发一个能够从文档和数据库中回答查询的聊天机器人&…...

Cursor AI开发微信小程序教程

1. 准备工作 在开始开发之前&#xff0c;需要完成以下准备工作&#xff1a; 1.1 安装微信开发者工具 前往微信开发者工具官网下载并安装适合操作系统的开发者工具。注册微信小程序账号&#xff0c;登录微信公众平台&#xff08;https://mp.weixin.qq.com&#xff09;&#…...

2025常用的SEO工具有哪些?

在互联网时代&#xff0c;如何让自己的网站或内容脱颖而出&#xff0c;成为许多企业和个人站长们最关注的问题。而在这个过程中&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;作为一种有效的提升网站曝光度和吸引流量的手段&#xff0c;已经成为了网站运营的核心之一。对…...

支持直接升级到21c的 Oracle 数据库版本

一、支持直接升级的版本 可以从以下版本直接升级到新版本&#xff1a; • 19c (所有版本) • 18c (所有版本) • 12c Release 2 (12.2) 升级到最新Oracle数据库版本必须采用的路径取决于当前数据库的版本号。 如果当前的Oracle数据库版本早于12.2 版&#xff0c;则无法直接将…...

线程池-抢票系统性能优化

文章目录 引言-购票系统线程池购票系统-线程池优化 池化 vs 未池化 引言-购票系统 public class App implements Runnable {private static int tickets 100;private static int users 10000;private final ReentrantLock lock new ReentrantLock(true);public void run() …...

回顾Golang的Channel与Select第一篇

深入解析Golang Channel与Select&#xff1a;并发编程的艺术与哲学 一、通信顺序进程&#xff08;CSP&#xff09;的Go实现 Go语言创始人Rob Pike将CSP理论具象化为channel原语&#xff0c;实现了"不要通过共享内存来通信&#xff0c;而要通过通信来共享内存"的哲学…...