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

Linux | Linux进程万字全解:内核原理、进程状态转换、优先级调度策略与环境变量

目录

1、从计算机组成原理到冯诺依曼架构

计算机系统的组成

冯诺依曼体系

思考:为什么计算机不能直接设计为 输入设备-CPU运算-输出设备 的结构?

2、操作系统(Operator System)

概念

设计OS的目的

描述和组织被管理对象

3、进程

基本概念

进程id和父进程id

进程 ID (PID):

父进程 ID (PPID):

C语言利用系统调用接口获取PID、PPID:

进程描述-PCB进程控制块

task_struct内容分类

查看进程

简单的进程监控脚本

在C语言中通过系统调用fork函数创建进程

fork() 系统调用:

示例1:使用 fork() 创建新进程,并通过返回值区分父子进程

示例2:使用 fork() 创建新进程,并打印相关信息

4、进程状态

进程状态概览

僵尸状态(子进程结束却没被父进程回收)

形成僵尸进程的条件

僵尸进程的危害

示例代码:创建并观察僵尸进程

孤儿状态(父进程结束子进程还在)

孤儿进程的形成:

孤儿进程的处理:

示例:孤儿进程的形成和处理:

5、进程调度与优先级

基本概念

查看系统进程

PRI 和 NI

操作:在bash中通过pid调整特定进程优先级

6、环境变量:操作系统的隐秘力量

基本概念

常见环境变量

查看和设置环境变量

环境变量的组织方式

示例1:通过main函数参数获取

示例2:通过extern变量获取

示例3:通过getenv()和putenv()接口操作单个环境变量

环境变量和普通变量的区别:环境变量具有全局属性


Linux进程

在现代计算机系统中,Linux操作系统以其开源、灵活和强大的特性,成为服务器和嵌入式系统的首选。了解Linux的进程管理机制对于系统管理员和开发者来说至关重要。

1、从计算机组成原理到冯诺依曼架构
计算机系统的组成

计算机组成原理告诉我们,所有的计算机系统都由一下结构组成:

  1. 输入设备:如键盘和鼠标,用于向计算机输入信息。
  2. 中央处理器(CPU):计算机的大脑,负责处理数据和执行命令。

CPU分为:运算器和控制器

运算器——算数运算、逻辑运算

控制器——响应外部事件、如拷贝磁盘数据到内存当中

  1. 存储器:内存(RAM)用于临时存储程序和数据。
  2. 输出设备:如显示器和打印机,用于展示信息和打印文档。

冯诺依曼体系

冯·诺依曼架构的最关键特点是程序指令和数据都存储在内存中,并且CPU可以直接访问内存来读取指令和数据。所有的输入和输出操作都是通过内存来进行的,即数据首先被写入内存,然后CPU从内存中读取数据进行处理,处理结果再写回内存,最后通过输出设备显示或打印出来。通俗的说,CPU大脑只和内存打交道,不和其它设备直接沟通。内存在冯诺依曼架构中充当中间件的作用。

笔记:我们常说的IO流是指内存和外设之间的通信!

思考:为什么计算机不能直接设计为 输入设备-CPU运算-输出设备 的结构?

其中一个原因是,计算机需要存储程序和数据。如果没有存储器,CPU将无法记住程序指令和处理的数据。但更本质的原因是CPU的运算速度远远超过大多数输入和输出设备,如果没有内存作为数据缓冲区,CPU在等待慢速的输入设备(如键盘或鼠标)提供数据或等待输出设备(如打印机或显示器)处理数据时,将会浪费大量计算资源。(CPU的执行过程也是流水线 木桶原理告诉我们 计算总时间取决于木桶的短板~)

2、操作系统(Operator System)

操作系统(Operating System,简称OS)是计算机系统中最基本的系统软件,它负责管理和控制计算机硬件和软件资源。操作系统在整个计算机软硬件架构中,定位为“管理”的软件,它处于应用软件和硬件之间的中间层,使用面向对象的思想,先描述资源,再管理资源,使得用户能够方便地使用计算机。

概念

操作系统是一组程序,它提供了计算机硬件和用户应用程序之间的接口。操作系统的主要功能包括:

  • 内核:操作系统的核心部分,负责进程管理、内存管理、文件系统管理和设备驱动程序管理等。
  • 其他程序:如函数库、Shell(命令行界面)、图形用户界面(GUI)等,这些程序为用户提供了与操作系统交互的接口。
设计OS的目的
  1. 与硬件交互:操作系统是计算机硬件的直接管理者,它通过内核与硬件进行交互,实现对硬件资源的控制。
  2. 管理软硬件资源:操作系统负责分配和管理CPU时间、内存、存储设备和输入输出设备等资源。
  3. 提供执行环境:为用户程序(应用程序)提供执行所需的环境,包括文件系统、网络通信、安全机制等。
描述和组织被管理对象
  • 硬件资源:CPU、内存、存储设备、输入输出设备等。
  • 软件资源:用户程序、系统程序、库文件等。

3、进程
基本概念
  • 课本概念:进程是程序的一个执行实例,是正在执行的程序。
  • 内核观点:进程是分配系统资源(如CPU时间和内存)的实体。

进程id和父进程id

进程 ID(Process ID,PID)和父进程 ID(Parent Process ID,PPID)是操作系统中用于标识和管理进程的关键属性

进程 ID (PID)
  • 每个运行中的进程都有一个唯一的数字标识符,称为 PID。
  • PID 是由操作系统分配的,用于区分系统中的每个进程。
  • 它通常从1开始递增,但操作系统重启后会重置。
  • 可以通过命令如 ps 来查看系统中所有进程的 PID。
父进程 ID (PPID)
  • 每个进程都有一个父进程,除了初始进程(通常 PID 为1 的进程,如 init 进程)。
  • PPID 是指启动当前进程的父进程的 PID。
  • 父进程可以控制子进程的执行,例如发送信号、终止子进程等。
  • 当父进程终止时,子进程通常会被 init 进程接管,init 进程的 PID 通常为 1.
C语言利用系统调用接口获取PID、PPID:
  • getpid():这是一个系统调用,用于获取调用进程的 PID。
  • getppid():这也是一个系统调用,用于获取调用进程的父进程的 PID。
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main() {printf("pid: %d\n", getpid());printf("ppid: %d\n", getppid());return 0;
}
进程描述-PCB进程控制块
  • PCB是存储进程信息的数据,结构进程的属性集合被存储在PCB中。
  • 在Linux操作系统中,描述进程的结构体是task_struct
  • 在Linux内核源代码中,所有进程以task_struct双向链表的形式被组织起来

task_struct内容分类
  • 标示符:进程的唯一标识符。
  • 状态:包括任务状态、退出代码、退出信号等。
  • 优先级:进程相对于其他进程的优先级。
  • 程序计数器:指向程序中即将执行的下一条指令的地址。
  • 内存指针:指向程序代码、进程数据以及共享内存的指针。
  • 上下文数据:处理器寄存器中的数据,用于进程切换时保存和恢复状态。
  • I/O状态信息:包括I/O请求、分配的I/O设备和使用的文件列表。
  • 记账信息:可能包括处理器时间、使用的时钟数、时间限制和账号信息。
  • other...

查看进程
  • 目录/proc下存在进程的相关信息(进程产生时创建、销毁时删除,目录名为进程PID),进程信息可以通过/proc系统文件夹查看,例如/proc/1包含PID为1的进程信息。
  • 用户级工具如topps也可以用来获取进程信息。
🔔

常用命令解释:ps axj | head -1 && ps axj | grep ...

  1. ps axj
  • ps:进程状态命令。
  • ax:显示所有进程,包括其他用户的进程。a 表示显示其他用户的进程,x 表示显示没有控制终端的进程。
  • j:使用 jobs 格式来显示进程信息,这种格式将进程的相关信息以易于阅读的方式展示,包括进程的父子关系。
  1. head -1
  • head:一个命令,用于显示文件的开始部分,默认情况下显示前10行。
  • -1:选项,表示只显示一行。在这个上下文中,它与 ps axj 结合使用,只显示进程列表的第一行,这通常是列标题。
  • ps axj | head -1用于打印ps命令字段含义。
  1. &&
  • 逻辑与操作符。用来执行&&前后两条命令则执行后面的命令。
  1. grep ...
  • grep:一个文本搜索工具,用于搜索包含指定模式的行。
  • ...:需要搜索的进程名称。
  • ps axj | grep ...用于打印ps命令经过grep命令筛选后特定的字段内容。

首先显示所有进程的标题行,如果成功显示,则继续执行第二个命令,即显示所有进程的列表,并过滤出包含特定模式的进程。

简单的进程监控脚本

ps axj | head -1 && ps axj | grep ...的基础上可以设计一个循环shell脚本,一秒钟查询一次进程状态。

while :; do ps axj | head -1 && ps axj | grep ...; echo ""; sleep 1; done

在C语言中通过系统调用fork函数创建进程

fork() 是一个在 Unix 和类 Unix 操作系统中创建新进程的系统调用。它是进程创建的基础,并且是多任务和多线程编程中非常重要的一部分。

fork() 系统调用
  • fork() 创建一个新的进程,这个新进程是调用进程的一个副本。
  • fork() 返回两次:一次在父进程中(返回子进程的 PID),一次在子进程中(返回 0)。
  • 如果 fork() 调用失败,它会在父进程中返回 -1,并且设置全局变量 errno 以指示错误。
  • fork() 之后,父进程和子进程将从 fork() 调用之后的代码点继续执行,这可能导致代码的重复执行。通常使用 if 语句来区分父进程和子进程的行为。
  • 子进程继承了父进程的所有资源,但是它们拥有不同的 PID 和 PPID。
  • 在使用 fork() 创建大量子进程时,需要考虑资源限制和僵尸进程问题(后续进程状态介绍)。

示例1:使用 fork() 创建新进程,并通过返回值区分父子进程
#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) { // 子进程printf("I am child : %d!, ret: %d\n", getpid(), ret);} else { // 父进程printf("I am father : %d!, ret: %d\n", getpid(), ret);}sleep(1);return 0;
}
示例2:使用 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;
}

4、进程状态

Linux 系统中的进程管理是操作系统的核心功能之一。Linux内核定义了多种进程状态,包括运行(R)、睡眠(S)、不可中断睡眠(D)、停止(T)、追踪停止(t)、死亡(X)和僵尸(Z)。

进程状态概览

在 Linux 内核中,进程(或称为任务)可以处于以下状态:

  1. 运行状态 (R - Running)
    • 进程正在使用 CPU,或者在 CPU 运行队列中等待被调度。
  2. 睡眠状态 (S - Sleeping)
    • 进程正在等待某个事件发生,如网络响应或文件 I/O 完成。这种睡眠是可中断的,进程可以被唤醒。
  3. 磁盘休眠状态 (D - Disk Sleep)
    • 进程正在进行 I/O 操作,如磁盘读写,但无法被中断。这种状态也称为不可中断睡眠状态。
  4. 停止状态 (T - Stopped)
    • 进程被 SIGSTOP 信号停止,通常用于调试或系统管理。进程可以通过 SIGCONT 信号恢复运行。
  5. 追踪停止状态 (t - Tracing Stop)
    • 进程因为某些原因被系统调用或工具追踪并停止,通常用于系统分析和监控。
  6. 死亡状态 (X - Dead)
    • 进程已经结束其执行,但尚未从进程表中完全移除。这是一个过渡状态,系统将很快回收其资源。
  7. 僵尸状态 (Z - Zombie)
    • 进程已经结束,但父进程尚未读取其退出状态。僵尸进程占用系统资源,尤其是进程 ID,直到父进程调用 wait()waitpid() 函数。
/*
* 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 * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};

僵尸状态(子进程结束却没被父进程回收)

僵尸进程(Zombie Process)是 Linux 和类 Unix 系统中一种特殊的进程状态。在这种状态下,进程已经完成其执行,但它的进程描述符(PCB)仍然保留在系统中。这种状态的进程不占用 CPU 资源,但它们仍然占用一个进程 ID(PID)和其他一些资源。

形成僵尸进程的条件
  1. 子进程退出:子进程完成其任务后调用 exit() 或者返回从 main() 函数,这会导致子进程退出。
  2. 父进程未读取状态:如果父进程没有调用 wait()waitpid() 来读取子进程的退出状态,子进程就会变成僵尸状态。
僵尸进程的危害
  1. 占用进程 ID:僵尸进程继续占用一个进程 ID,这在系统资源有限的情况下可能是个问题。
  2. 内存泄漏:虽然僵尸进程不占用 CPU 资源,但它们仍然保留在进程表中,进程表本质是一个结构体,也需要占用系统内存资源,造成了内存泄露
示例代码:创建并观察僵尸进程
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main() {pid_t id = fork();if (id < 0) {perror("fork");return 1;} else if (id > 0) { // 父进程printf("Parent[%d] is sleeping...\n", getpid());sleep(30); // 父进程睡眠,不读取子进程状态,形成僵尸进程} else if(id == 0){ // 子进程printf("Child[%d] is beginning...\n", getpid());sleep(5);exit(0);}return 0;
}
  • 程序开始时,父进程被创建。
  • 父进程通过 fork() 创建子进程。
  • 子进程打印开始消息,休眠5秒,然后退出。
  • 父进程打印正在睡眠的消息,然后休眠30秒。由于父进程在sleep时间内不检查子进程的状态,子进程在退出后会变成僵尸进程。

孤儿状态(父进程结束子进程还在)

孤儿进程(Orphan Process)是其父进程已终止,但子进程仍在运行的进程。在类 Unix 系统中,孤儿进程会被 init 进程(通常是 PID 为 1 的进程)领养,并最终由 init 进程回收。

孤儿进程的形成:
  1. 父进程退出:父进程由于某种原因(如正常退出、被终止等)而结束运行。
  2. 子进程仍在运行:在父进程退出时,如果有任何子进程仍在运行,这些子进程就会变成孤儿进程。
孤儿进程的处理:
  1. init 进程领养:系统会自动将孤儿进程的父进程设置为 init 进程(PID 为 1)。
  2. 状态变更:孤儿进程在结束运行后,会进入僵尸状态(Zombie State),等待 init 进程读取其退出状态。
  3. 资源回收init 进程会周期性地检查并回收孤儿进程的资源,包括其进程描述符等。
示例:孤儿进程的形成和处理:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>int main() {pid_t pid = fork(); // 创建子进程if (pid < 0) {perror("fork failed");exit(EXIT_FAILURE);}if (pid == 0) {// 子进程printf("Child process, PID: %d, PPID: %d\n", getpid(), getppid());// 子进程继续运行,模拟父进程退出后的场景sleep(10);} else {// 父进程退出,子进程成为孤儿进程printf("Parent process, PID: %d, exiting and leaving child orphaned.\n", getpid());sleep(3);_exit(0);}// 子进程代码不会被执行,因为父进程已经退出return 0;
}

在这个示例中,父进程创建了一个子进程,然后立即退出。这导致子进程成为孤儿进程。在实际系统中,init 进程会接管这个孤儿进程,并在其退出后回收资源。

5、进程调度与优先级

在 Linux 系统中,进程优先级决定了 CPU 资源的分配顺序。进程优先级可以通过nice值调整,nice值的范围是-20至19,nice值越小进程优先级越高。进程调度是操作系统的核心功能之一,它决定了进程执行的顺序。

基本概念
  • 进程优先权(Priority):决定了进程被 CPU 执行的先后顺序。优先权高的进程会优先获得 CPU 时间。
  • 多任务环境:在多任务环境中,合理配置进程优先级可以显著改善系统性能。

查看系统进程

在 Linux 或 Unix 系统中,可以使用 ps -l 命令来查看系统进程列表。

输出将包括以下重要信息:

  • UID:用户 ID,表示执行进程的用户身份。
  • PID:进程 ID,是进程的唯一标识。
  • PPID:父进程 ID,表示该进程是由哪个父进程创建的。
  • PRI:进程的优先级。
  • NI:nice 值,表示进程优先级的修正数值。

PRI 和 NI
  • PRI:进程的原始优先级,数值越小表示优先级越高。
  • NI:nice 值,用于调整进程的优先级。计算新的优先级公式为 PRI(new) = PRI(old) + NI
  • nice 值的范围:从 -20 到 19,共 40 个级别。正值表示降低进程优先级,负值表示提高进程优先级。

注意:nice 值不是进程的优先级,而是进程优先级允许调整的范围。可以将其视为对原始优先级的一个修正。通过调整 nice 值,可以控制进程的相对优先级,从而影响 CPU 资源的分配。

最终,操作系统更具PRI(new)的值,按从小到大的优先级执行。

操作:在bash中通过pid调整特定进程优先级
  • 使用 top 命令可以动态查看进程优先级。
  • r 键来调整指定pid进程的 nice 值。

6、环境变量:操作系统的隐秘力量

引入:我们知道,在 Linux 系统中,确实“一切皆文件”,命令的本质是一个可执行程序(大部分是c语言编译而来的可执行程序),命令名其实就是文件名,命令可以不需要完整路径就能执行。例如:只需要输入ls命令就可以执行对应的程序,获取目录内的文件。但是,为什么我们自己写的程序必须要带完整的文件路径才可以执行(./main),而命令程序只需要文件名即可?这背后的原理涉及到 Linux 的文件系统和环境变量,尤其是 PATH 环境变量。

基本概念

环境变量为操作系统、系统上的应用程序和用户shell提供了一个传递配置信息的方法。它们可以告诉系统在哪里找到所需的文件,如何配置特定的程序,或者在shell中定义别名等。

常见环境变量
  • PATH:定义了操作系统搜索可执行文件的目录顺序。例如,当你在终端输入一个命令时,系统会在PATH变量指定的目录中查找这个命令,发现相应文件就可以直接执行(相当于自动补全文件路径)。当我们把我们自己写的代码目录放入PATH环境变量之后,也能向命令一样只需要输入文件名即可执行。(相关的修改操作后半部分介绍~)

  • HOME:指向用户的主目录。当你登录系统时,这是你的默认工作目录。
  • SHELL:表示当前用户使用的shell类型,通常的值是/bin/bash

查看和设置环境变量
  • 查看环境变量:可以使用echo $NAME命令来打印特定的环境变量值,其中NAME是环境变量的名称。
  • 设置环境变量
    • 使用export命令创建或修改环境变量,如export PATH=$PATH:/new/directory/path
    • 使用env命令可以查看所有当前的环境变量。
  • 清除环境变量:使用unset命令可以删除一个环境变量。
  • 显示所有本地变量:使用set命令可以显示当前shell会话中定义的所有本地变量和环境变量。
📌

1. echo: 显示某个环境变量值

2. export: 设置一个新的环境变量

3. env: 显示所有环境变量

4. unset: 清除环境变量

5. set: 显示本地定义的shell变量和环境变量

环境变量的组织方式

程序在运行时,main函数第三个参数(也是最后一个参数)会被转入一张环境变量表

示例1:通过main函数参数获取
#include<stdio.h>
int main(int argc, char* argv, char** env)
{int i = 0;while(env[i]){printf("env[%d]->%s\n",i,env[i]);i++;}return 0;
}

示例2:通过extern变量获取
#include <stdio.h>
int main()
{extern char **environ;int i = 0;for(; environ[i]; i++){printf("env[%d]->%s\n", i, environ[i]);}return 0;
}

示例3:通过getenv()和putenv()接口操作单个环境变量

getenvputenv 是两种用于处理环境变量的函数,它们分别用于获取和设置环境变量的值。下面是对这两个函数的介绍,包括它们所属的头文件、函数原型、参数、返回值以及一些使用示例。

getenv

  • 头文件#include <stdlib.h>
  • 函数原型
char *getenv(const char *name);
  • 参数
    • name:一个指向以 null 结尾的字符串的指针,指定要查询的环境变量名称。
  • 返回值
    • 如果环境变量存在,返回指向该环境变量值的指针。
    • 如果环境变量不存在,返回 NULL
#include <stdio.h>
#include <stdlib.h>int main() {const char *homeDir = getenv("HOME");if (homeDir != NULL) {printf("The HOME environment variable is set to: %s\n", homeDir);} else {printf("The HOME environment variable is not set.\n");}return 0;
}

putenv

  • 头文件#include <stdlib.h>(在某些系统上可能需要 #include <unistd.h>
  • 函数原型
int putenv(char *string);
  • 参数
    • string:一个指向以 null 结尾的字符串的指针,该字符串应该包含环境变量的名称和值,格式为 name=value
  • 返回值
    • 成功时返回 0。
    • 失败时返回非零值。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main() {// 设置环境变量const char *envVar = "MY_VAR=value";if (putenv((char *)envVar) == 0) {printf("Environment variable set successfully.\n");} else {perror("Failed to set environment variable");}// 验证设置是否成功const char *value = getenv("MY_VAR");if (value != NULL) {printf("MY_VAR is now set to: %s\n", value);} else {printf("MY_VAR is not set.\n");}return 0;
}
  • 使用 putenv 时,传入的字符串 string 必须以 name=value 的格式存在,并且 string 指向的内存在函数调用后不应被释放或修改,因为 putenv 可能会修改这个字符串。
  • 在多线程环境中,使用 putenv 可能不是线程安全的。在这种情况下,可以考虑使用 setenvunsetenv(如果可用),这些函数提供了线程安全的替代。
  • 环境变量的更改通常只影响当前进程及其子进程,不会影响其他进程或父进程的环境变量。
环境变量和普通变量的区别:环境变量具有全局属性

环境变量具有全局属性,意味着它们可以在操作系统的不同进程之间共享。当一个程序运行时,它通常会从其父进程那里继承环境变量。这种继承机制允许程序访问由操作系统或其它程序设置的配置信息。

当你在命令行中设置一个环境变量,比如使用 export my_env ="lihongyu" 命令,实际上是在当前的shell会话中设置了这个变量。这个变量会立即在当前shell会话中可用,并且所有从这个shell启动的子进程也会继承这个变量。

如果你只设置环境变量而不使用 export 命令,比如 my_env="lihongyu",那么这个变量只会在当前的shell会话中存在,而不会被子进程继承。这是因为只有通过 export 命令,变量才会被标记为可导出,从而被子进程继承。

#include<stdio.h>
#include<stdlib.h>
int main()
{const char* env = getenv("my_env");if(env){printf("%s\n", env);}return 0;
}

一个简单的实验,发现环境变量的继承和普通变量的区别在于:

  • 作用域:普通变量只在当前shell会话中有效,而环境变量可以跨会话和进程边界。
  • 继承:环境变量可以被子进程继承,而普通变量则不能。
  • 生命周期:普通变量的生命周期仅限于当前shell会话,环境变量则可以持续存在于操作系统中,直到被显式地修改或删除。

相关文章:

Linux | Linux进程万字全解:内核原理、进程状态转换、优先级调度策略与环境变量

目录 1、从计算机组成原理到冯诺依曼架构 计算机系统的组成 冯诺依曼体系 思考&#xff1a;为什么计算机不能直接设计为 输入设备-CPU运算-输出设备 的结构&#xff1f; 2、操作系统(Operator System) 概念 设计OS的目的 描述和组织被管理对象 3、进程 基本概念 进程id和父进程…...

VBA技术资料MF184:图片导入Word添加说明文字设置格式

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…...

在函数设计中应用单一职责原则:函数分解与职责分离

在函数设计中应用单一职责原则&#xff1a;函数分解与职责分离 引言 单一职责原则&#xff08;Single Responsibility Principle, SRP&#xff09;是面向对象设计原则中的核心原则之一&#xff0c;强调一个类或函数应该只有一个责任或理由去改变。在函数设计中&#xff0c;应…...

多线程锁机制面试

目录 乐观锁的底层原理 ReentrantLock的实现原理 读写锁 ReentrantReadWriteLock synchronized 底层原理 Lock和synchronized的区别 乐观锁的底层原理 版本号机制 在数据库表中添加一个版本号字段&#xff08;如 version&#xff09;&#xff0c;每次更新数据时都会将版本号…...

《SQL 中计算地理坐标两点间距离的魔法》

在当今数字化的世界中&#xff0c;地理数据的处理和分析变得越来越重要。当我们面对一个包含地理坐标数据的表时&#xff0c;经常会遇到需要计算两点之间距离的需求。无论是在物流配送路线规划、地理信息系统应用&#xff0c;还是在基于位置的服务开发中&#xff0c;准确计算两…...

微服务可用性设计

一、隔离 对系统或资源进行分割&#xff0c;实现当系统发生故障时能限定传播范围和影响范围。进一步的&#xff0c;通过隔离能够降低系统之间得耦合度&#xff0c;使得系统更容易维护和扩展。某些业务场景下合理使用隔离技巧也能提高整个业务的性能。我理解隔离本质就是一种解…...

【扒代码】dave readme文档翻译

jerpelhan/DAVE (github.com) 摘要 低样本计数器估算选定类别对象的数量&#xff0c;即使在图像中只有少量或没有标注样本的情况下。目前最先进的技术通过对象位置密度图的总和来估算总数量&#xff0c;但这种方法无法提供单个对象的位置和大小&#xff0c;这对于许多应用来说…...

c语言---文件

这一节我准备分三个部分来带领大家了解文件 ——一、有关文件的基础知识 ————二、文件的简单操作 ————————三、文件结束的判定 ————————————四、文件缓冲区 一、文件的基础知识&#xff1a; 首先在了解文件之前&#xff0c;我们需要了解C/C程序内存…...

Windows系统下Go安装与使用

step1&#xff1a; 下载go语言SDK 下载地址&#xff1a;https://go.dev/dl/ 下载后选择合适位置安装即可&#xff0c;我选择D盘 在安装完成后&#xff0c;可以通过go env 命令检测是否安装成功。在“命令提示符”界面输入“go env”命令&#xff0c;如果显示如下类似结果则说明…...

day24-测试之接口测试基础

目录 一、接口的定义 二、接口的优点 三、API接口 四、接口测试流程 五、网络基础概念 六、HTTP和RURL 七、get和post请求 八、数据格式 九、状态码 十、restful风格 十一、接口工具 一、接口的定义 程序之间协作所要遵循的一套规范、标准 二、接口的优点 2.1.责任…...

TSN 交换机

TSN&#xff08;Time-Sensitive Networking&#xff09;交换机是一种支持时间敏感网络协议的网络交换设备&#xff0c;用于在以太网网络中实现低延迟、高确定性的数据传输。TSN 是一组 IEEE 802 标准的集合&#xff0c;旨在通过标准化的方式&#xff0c;将传统的以太网扩展到需…...

针对thinkphp站点的漏洞挖掘和经验分享

0x1 前言 浅谈 目前在学习和研究thinkphp相关漏洞的打法&#xff0c;然后最近对于thinkphp资产的收集方面有了一个简单的认识&#xff0c;然后写一篇新手看的thinkphp相关的漏洞收集和挖掘的文章来分享下。然后后面是给师傅们分享下后台文件上传&#xff0c;然后直接打一个ge…...

MySQL数据库入门,pycharm连接数据库—详细讲解

一.安装MySQL 1.常用MySQL5.7&#xff0c;首先安装MySQL&#xff0c; &#xff08;一&#xff09; &#xff08;二&#xff09; &#xff08;三&#xff09; &#xff08;四&#xff09; &#xff08;五&#xff09; 2.配置环境变量 打开MySQL安装路径&#xff0c;在其中找到…...

.bat文件快速运行vue项目

如何使用bat文件快速运行vue项目&#xff1f; 新建个文件&#xff0c;改名为serve.bat。 在文件中写入以下内容&#xff1a; # cd 项目路径 cd D:\projects\xxx npm run serve pausecd 项目所在的路径 npm run dev/serve &#xff0c;取决于项目的启动方法&#xff0c;打…...

数据结构(邓俊辉)学习笔记】优先级队列 07——堆排序

1.算法 作为完全二叉堆的一个应用&#xff0c;这节来介绍堆排序算法。 是的&#xff0c;谈到优先级队列&#xff0c;我们很自然地就会联想到排序。因为就其功能而言&#xff0c;包括完全二叉堆在内的任何一种优先级队列都天生地具有选取功能&#xff0c;也就是选取其中的最大…...

npm install pnpm -g 报错的解决方法

npm install pnpm -g 报错的解决方法 npm error code ETIMEDOUT npm error errno ETIMEDOUT npm error network request to https://registry.npmjs.org/pnpm failed, reason: npm error network This is a problem related to network connectivity. npm error network In mo…...

集师知识付费小程序开发

智慧生活&#xff0c;从选择一款优质知识付费小程序起航 在这个信息爆炸的时代&#xff0c;知识成为了最宝贵的财富。我们渴望不断学习&#xff0c;提升自我&#xff0c;追求更高品质的生活。而一款优质的知识付费小程序&#xff0c;就如同照亮前行道路的明灯。 它是知识的宝库…...

前端开发提效工具——用户自定义代码片段

做开发总是会有大量的代码要写&#xff0c;但是有时候某些代码是非常基础但是很多&#xff0c;我们就可以把这一部分整合起来&#xff0c;使用一个很简短的关键字来快速唤出。 如何新建这样的代码段&#xff1f; 1.在VSCode当中找到Snippets&#xff0c;然后点击 2.之后会弹出…...

docker容器安全加固参考建议——筑梦之路

这里主要是rootless的方案。 在以 root 用户身份运行 Docker 会带来一些潜在的危害和安全风险&#xff0c;这些风险包括&#xff1a; 容器逃逸&#xff1a;如果一个容器以 root 权限运行&#xff0c;并且它包含了漏洞或者被攻击者滥用&#xff0c;那么攻击者可能会成功逃出容器…...

基于 Appium 的 App 爬取实战

除了运行 Appium 的基本条件外&#xff0c;还要一个日志输出库 安装&#xff1a; pip install loguru 思路分析 首先我们观察一下整个 app5 的交互流程&#xff0c;其首页分条显示了电影数据&#xff0c; 每个电影条目都包括封面&#xff0c;标题&#xff0c; 类别和评分 4…...

nvm与node安装

参考&#xff1a; 一文搞定NVM安装所有问题NVM UI解决nodejs下载慢问题 node_mirror: http://npmmirror.com/mirrors/node/ npm_mirror: http://registry.npmmirror.com/mirrors/npm/解决nvm list available报错问题 Could not retrieve https://npm.taobao.org/mirrors/node/…...

【电子通识】什么是MSL湿敏等级

潮敏失效是塑料封装表贴器件在高温焊接工艺中表现出来的特殊的失效现象。 造成此类问题的原因是器件内部的潮气膨胀后使得器件发生损坏。 MSL是“Moisture Sensitivity Level&#xff08;湿气敏感性等级&#xff09;”的缩写&#xff0c;针对需进行回流焊的产品设定了MSL基准。…...

【ARM 芯片 安全与攻击 5.4 -- Meltdown 攻击与防御介绍】

文章目录 什么是 Meltdown 攻击?Meltdown 攻击的基本原理Meltdown 攻击代码示例Meltdown 攻击在芯片中的应用应用场景Meltdown 攻击与瞬态攻击、测信道攻击的关系针对 Meltdown 攻击的防御硬件级防御Summary什么是 Meltdown 攻击? Meltdown 攻击是一种利用处理器乱序执行(o…...

Django 后端架构开发:分页器到中间件开发

&#x1f680; Django 后端架构开发&#xff1a;分页器到中间件开发 &#x1f680; &#x1f539; 应用样式&#xff1a;上下翻页 分页功能在处理大量数据时非常有用。通过上下翻页&#xff0c;我们可以让用户轻松浏览数据。以下是一个展示产品列表的分页示例&#xff1a; fr…...

亲测解决The client socket has failed to connect to

这个问题是因为深度学习的程序&#xff08;服务&#xff09;跟本地主机连接不上&#xff0c;解决方法是确认rank起始数为0。 报错原文 [W socket.cpp:663] [c10d] The client socket has failed to connect to [csdn-xiaohu]:12345 (errno: 22 - Invalid argument).解决方法 …...

Intel ACRN 安装WIN10 VM

上一篇帖子记录了ACRN运行rt linux&#xff0c;这篇帖子记录一下最近倒腾出来的WIN10。目前架构如下 ACRN可以把它理解为一个基于Linux类似软件的Type1 Hypervisor&#xff0c;基于Linux去做而不是baremetal是为了更方便去配置资源。 首先我们得有两台电脑&#xff0c;一台是开…...

贷齐乐案例

源码分析&#xff1a; <?php // 设置 HTTP 头部&#xff0c;指定内容类型为 text/html&#xff0c;字符集为 utf-8 header("Content-type: text/html; charsetutf-8"); // 引入数据库配置文件 require db.inc.php; // 定义函数 dhtmlspecialchars&#xff0c;用…...

[Qt][Qt 网络][下]详细讲解

目录 1.TCP Socket1.核心API概览2.回显服务器3.回显客户端 2.HTTP Client3.其他模块 1.TCP Socket 1.核心API概览 核⼼类是两个&#xff1a;QTcpServer和QTcpSocketQTcpServer用于监听端口&#xff0c;和获取客户端连接 listen(const QHostAddress&, quint16 port)&#…...

十三、OpenCVSharp的目标检测

文章目录 简介一、传统目标检测方法1. 基于滑动窗口的检测2. 特征提取与分类器结合(如 HOG + SVM)3. 级联分类器二、基于深度学习的目标检测1. YOLO 系列算法2. SSD 算法3. Faster R-CNN 算法三、深度学习目标检测模型的训练和部署四、目标检测的性能评估指标1. 准确率、召回…...

STM32标准库学习笔记-6.定时器-输入捕获

参考教程&#xff1a;【STM32入门教程-2023版 细致讲解 中文字幕】 定时器输入捕获 IC&#xff08;Input Capture&#xff09;输入捕获输入捕获模式下&#xff0c;当通道输入引脚出现指定电平跳变时&#xff0c;当前CNT的值将被锁存到CCR中&#xff0c;可用于测量PWM波形的频率…...

vue前端可以完整的显示编辑子级部门,用户管理可以为用户分配角色和部门?

用户和角色是一对多的关系用户和部门是多对多得关系<template><div class="s"><!-- 操作按钮 --><div class="shang"><el-input v-model="searchText" placeholder="请输入搜索关键词" style="width:…...

量化交易的基石:ExchangeSdk

作为长期混迹在合约市场的老韭菜来说&#xff0c;已不能满足与手动下单来亏钱&#xff0c;必须得通过脚本来加速&#xff0c;为了达到这个目的就产生了项目。目前封装的主要是合约的API接口&#xff0c;不支持现货交易。 Github: https://github.com/silently9527/exchange-sdk…...

【区块链+金融服务】基于区块链的一站式绿色金融开放平台 | FISCO BCOS应用案例

科技的进步为绿色金融发展提供了新的机遇&#xff0c;但银行、企业、第三方金融机构等在进行绿色金融业务操作过程中&#xff0c; 存在着相关系统和服务平台建设成本高、迭代难度大、数据交互弱、适配难等痛点。 基于此&#xff0c;中碳绿信采用国产开源联盟链底层平台 FISCO …...

使用Python实现深度学习模型:智能娱乐与虚拟现实技术

介绍 智能娱乐与虚拟现实(VR)技术正在改变我们的娱乐方式。通过深度学习模型,我们可以创建更加沉浸式和智能化的娱乐体验。本文将介绍如何使用Python和深度学习技术来实现智能娱乐与虚拟现实的应用。 环境准备 首先,我们需要安装一些必要的Python库: pip install pand…...

亚马逊云科技产 Amazon Neptune 图数据库服务体验

目录 图数据库为什么使用图数据库Amazon Neptune实践登陆创建 S3 存储桶notebook图神经网络快速构建加载数据配置端点Gremlin 查询删除环境删除 S3 存储桶 总结 图数据库 图数据库是一种专门用于存储和处理图形数据结构的数据库管理系统。图形数据结构由节点&#xff08;Node&…...

【网络安全】重置密码token泄露,实现账户接管

未经许可&#xff0c;不得转载。 文章目录 正文 正文 对某站点测试过程中&#xff0c;登录账户触发忘记密码功能点&#xff0c;其接口、请求及响应如下&#xff1a; PUT /api/v1/people/forgot_password 可以看到&#xff0c;重置密码token和密码哈希均在响应中泄露。 删除co…...

计算机基础知识复习8.13

cookie和session区别 cookie:是服务器发送到浏览器&#xff0c;并保存在浏览器端的一小块数据 浏览器下次访问服务时&#xff0c;会自动携带该块数据&#xff0c;将其发送给服务器 session:是javaEE标准&#xff0c;用于在服务端记录客户端信息 数据存放在服务端更加安全&a…...

Unity URP无光照下Shadow 制作 <二> 合批处理

闲谈 相信大家在日常工作中发现了一个问题 &#xff0c; urp下虽然可以做到3个Pass 去写我们想要的效果&#xff0c;但是&#xff0c;不能合批&#xff08;不能合批&#xff0c;那不是我们CPU要干冒烟~&#xff01;&#xff09; 好家伙&#xff0c;熊猫老师的偏方来了 &#x…...

微乐校园pf

TOC springboot451微乐校园pf 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;规范化管理。这…...

文件其他相关函数

symlink 链接文件: file.txt -> hello.c 软链接文件、符号链接文件 硬链接文件 命令行&#xff1a;ln -s 123 softlink 快捷方式 int symlink(const char *oldpath, const char *newpath); 功能: 创建一个链接向oldpath文件的新符号链接文件 参数: oldpath:被链接向…...

SQLALchemy ORM 的关联关系之 ORM 中的多对多

SQLALchemy ORM 的关联关系之 ORM 中的多对多 场景示例实现多对多关系定义模型插入和查询数据总结在 SQLAlchemy ORM 中,多对多(Many-to-Many)关联关系是一种常见的关系类型,它表示两个表中的行可以相互关联,即一个表中的多行可以与另一个表中的多行相关联。为了实现这种关…...

sdkman install慢,采用squid代理

(1)A机器,IP:yy.yy.yy.yy 安装squid yum install squidvi /etc/squid/squid.confacl allowed_ip src xx.xx.xx.xx http_access allow allowed_ip http_access deny allsystemctl restart squid 开放3128端口 (2)B机器&#xff0c;IP:xx.xx.xx.xx, export http_proxyhttp://y…...

实时监控Windows服务器:使用Prometheus和Grafana的终极方案

视频指南 【1】快速上手&#xff1a;在Windows系统上部署Prometheus与Grafana&#xff0c;实时监控性能指标 【2】快速上手&#xff1a;在Windows系统上部署Prometheus与Grafana&#xff0c;实时监控性能指标 1. 下载并安装 Prometheus 下载 Prometheus&#xff1a; 访问 Pro…...

【文科生能看懂的】牛顿二项式定理

牛顿二项式定理 简单的二项式整数次幂展开的结果中的规律结果中各项的指数结果中各项的系数 二项式定理 牛顿二项式定理就是用来求某个二项式的整数次幂的展开式的。 简单的二项式整数次幂 我们可以先从简单的情况开始&#xff0c;比如二项式 ( a b ) (ab) (ab)的整数次幂&a…...

Fly Catcher:通过监测恶意信号来检测飞机欺骗

Fly Catcher 的开发者 Angelina Tsuboi 是一名飞行员、网络安全研究员和发明家。 她决定着手一个将这三个不同兴趣结合起来的项目&#xff0c;以解决航空雷达系统的一个重大问题。 ADS-B 系统最初用于基本的飞机定位和跟踪&#xff0c;Tsuboi 对该系统的网络安全方面进行了深…...

计算机网络——HTTP协议详解(上)

一、HTTP协议简单介绍 1.1 什么是HTTP协议 HTTP&#xff08;超文本传输协议&#xff09;是一种用于在Web浏览器和Web服务器之间传输数据的应用层协议。它是一种无状态协议&#xff0c;即服务器不会保留与客户端的任何连接状态信息&#xff0c;每个请求都被视为一个独立的事务。…...

十九、中介者模式

文章目录 1 基本介绍2 案例2.1 Developer 抽象类2.2 FrontendDeveloper 类2.3 BackendDeveloper 类2.4 Mediator 接口2.5 ProjectManager 类2.6 Client 类2.7 Client 类的运行结果2.8 总结 3 各角色之间的关系3.1 角色3.1.1 Colleague ( 同事 )3.1.2 ConcreteColleague ( 具体的…...

编程参考 - 头文件中使用static inline

在Linux kernel的头文件中&#xff0c;经常使用static inline来声明一个函数。 比如include/linux/delay.h中&#xff0c; static inline void ssleep(unsigned int seconds) { msleep(seconds * 1000); } static Keyword * 范围限制&#xff1a; 当应用于函数或变量时&#…...

Uniapp使用antd组件库

组件库官网 https://www.antdv.com/docs/vue/introduce-cn 安装 在命令行终端输入 npm uni --save ant-design-vue配置 我这里用的是uniapp的vue3版本模板 在main.js里面引入 只要改下面带序号的地方即可 import App from ./App// #ifndef VUE3 import Vue from vue im…...

计算机毕业设计选题推荐-高校实验室管理系统-Java/Python项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…...