轻松Linux-4.进程概念
屋漏偏逢连夜雨,今天就学Linux
话不多说,展示军火
1.认识冯诺依曼体系
冯诺依曼体系其实并不是什么稀罕的东西,我们生活中的笔记本、服务器、计算机等等大多都遵守冯诺依曼体系
非常经典的一张图
我们所认识的计算机,是由一个个硬件组成的
中央处理器(CPU):包含运算器、控制器等部件
输入设备:鼠标、键盘、画板等等
输出设备:显示器、打印机等等
存储器:硬盘(外存)、内存、高速缓存(CPU内的缓存,比如常听到的三缓)
2.操作系统(Operator System)
2.1 操作系统是什么
我们可以这么理解:任何计算机都包含操作系统,操作系统可以粗略分为内核和其他程序
内核:文件管理、进程管理、驱动管理、内存管理
其他程序:shell、bash、库函数等等
它的核心功能:管理系统内的各项任务、文件,是纯正的 “ 领导 ” ,就像你的校长
2.2 为什么设计OS
对底层:它与硬件交互,管理一切软硬件资源
对上层:它与用户程序(应用程序)交互,提供一个良好的软件运行环境
怎么“管理”:先描述,再组织 --先把每种数据定义成各种变量、结构体,然后通过数据结构来管理它们,例如:我是一个大学生,然后我的年龄、身高等等被写入一个个表格,然后我导就通过管理一份份这样的表格,来实现对大学生的管理
2.3 系统调用和库函数概念
再开发角度上看,操作系统对外表现为一个整体,操作体统会露出部分接口,给上层开发使用,这部分操作系统提供的接口,就是系统调用。
系统调用功能上相对比较基础,对用户下限要求较高,于是一些开发者大佬就对部分系统调用接口进行适度封装,然后就有了库,这样就更有利于上层用户使用和开发者做二次开发。
就相当于银行,它不像你直接开发金库,但是会给出服务窗口和ATM机
3.进程
3.1 基本概念与基本操作
课本概念:程序的一个执行实例,正在执行的程序等
内核观点:担当分配系统资源(CPU时间,内存)的实体。
3.1.2 描述进程-PCB
基本概念:
进程信息被放在一个叫进程控制块的数据结构里,可以理解成--进程属性集合
书上叫它PCB(process control block),Linux操作系统下就是task_struct
task_struct是PCB的一种
Linux系统中描述进程信息的结构体就是task_struct
task_struct是Linux内核中的一种数据结构,它包含着进程的信息,会被装载到RAM(内存)中
3.1.3 task_struct
内容分类
标识符 | 用来标识本进程的唯一标志,用于区别其他进程 |
状态 | 任务状态、退出代码、退出信息等等 |
优先级 | 相对于其它进程的优先级 |
程序计数器 | 程序中即将被执行的下一条指令的地址 |
内存指针 | 包含程序代码和进程相关信息的指针,和与其它进程共享内存的指针等等 |
上下文数据 | 进程执行时,处理器的寄存器中的数据 |
I/O状态信息 | 包括显示的 I/O请求,分配给进程的 I/O设备和被进程使用的文件列表 |
记账信息 | 可能包括处理器时间总和,使用的时钟总和,时间限制,记账号码等等 |
↓部分进程的源代码↓
还有其他很多信息,后面细说
组织进程
那么操作系统是怎么组织管理进程的呢?---------链表
在task_struct中存有链表的节点,OS通过该链表来管理进程
3.1.4 查看进程
例如,如果要查看PID为1的进程的信息,可以ls /proc/1来查看
我们可以通过系统调用获取进程标示符
进程PID,父进程PID
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>int main()
{printf("PID: %d",getpid());printf("PPID: %d",getppid());return 0;
}
3.1.5 创建子进程
可以用 man 2 fork来查看fork的信息
fork有两个返回值,并且父子进程共享代码数据,但是子进程是只读状态来访问父进程的代码
但子进程一旦修改写入某些变量,就会发生缺页异常(缺页中断),然后发生写时拷贝,这时
这个变量就在子进程创建了一份拷贝
这里可以看到父进程的pid:15235,子进程的pid:15236,且可以看到子进程的父进程pid,就是父进程的pid,并且父进程可以通过fork的返回值拿到子进程的pid
#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);}sleep(1);return 0;
}
根据fork的返回值,我们可以用 if 来对进程进行分流 ,父进程的ret为子进程的PID,子进程的ret则为0 ( 即fork的两个返回值 )
3.2 进程状态
我们为了知道进程在干什么,我们可以查看进程的状态,进程有多种状态(在Linux内核中,进程有时也叫任务)
我们来看一下Linux内核中代码的介绍:
R运行状态:这并不意味着进程就在运行,它可能在运行,也可能在运行队列中"排队",等待被调度。
S睡眠状态:意味着进程正在等待某件事情完成,有时也叫做中断睡眠(interruptible sleep)。
D磁盘睡眠状态:有时也叫不可中断睡眠(uninterruptible sleep),这个状态的进程通常会等待IO结束。
T停止状态:可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。
X死亡状态:这个状态只是一个 死亡状态 返回状态,你不会在任务列表里看到这个状态。
Z僵尸状态:这个状态的进程通常是在等待其父进程回收它信息,没被回收时会一直在任务列表中
3.2.1 进程状态查看
ps aux | ps axj 命令
a:显示一个终端所有的进程,包括其他用户的进程。
x:显示没有控制终端的进程,例如后台运行的守护进程。
j:显示进程归属的进程组ID、会话ID、父进程ID,以及与作业控制相关的信息
u:以用户为中心的格式显示进程信息,提供进程的详细信息,如用户、CPU和内存使用情况等
这些指令可以组合使用如:ps aux | ps aj 、ps aux | ps uj等等
↓源于网图↓
3.2.3 僵尸进程
僵尸状态:是一个比较特殊的进程状态,上面我们提到僵尸状态下的进程通常是在等待父进程回收它的信息。
当进程退出并且父进程(使用wait()系统调用,后面讲)没有读取到子进程退出的返回代码时就会产生僵死(尸)进程。
即子进程成为僵尸进程,父进程要使用系统调用wait()来回收子进程的退出信息。
这里可以看到子进程29772变为了Z状态即僵尸状态
这里是源代码
#include <stdio.h>
#include <stdlib.h>
int main()
{pid_t id = fork();if(id < 0){perror("fork");return 1;}else if(id > 0){ //parentprintf("parent[%d] is sleeping...\n", getpid());sleep(30);}else{printf("child[%d] is begin Z...\n", getpid());sleep(5);exit(EXIT_SUCCESS);}return 0;
}
僵尸进程的危害
子进程退出时的退出状态在被回收前一定要维持下去,因为它需要将退出信息交给父进程,它需要父进程了解它任务完成的情况。也就是说,只要父进程一直不回收,子进程就会一直处于Z僵尸状态。
维护进程的退出状态本身就是要用数据维护的,也属于进程的基本信息,会被保存在task_struct(PCB)中,只要子进程一直处于Z僵尸状态,OS就要一直维护它。这就会造成内存泄漏。
因为维护子进程的退出状态要在内存中开辟空间,来暂存它的状态信息,僵尸进程一多,就会造成大量的内存资源浪费。
3.2.2 孤儿进程
如果子进程还没结束,它的父进程就退出,那子进程进入Z状态之后,该怎么办?
父进程先于子进程退出,这种情况,子进程称为“孤儿进程”
不过,这个孤儿进程会被PID为1的进程领养,即被1号init进程领养,并由1号进程回收
看段代码
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{pid_t id = fork();if(id < 0){perror("fork");return 1;}else if(id == 0){//childprintf("I am child, pid : %d\n", getpid());sleep(10);}else{//parentprintf("I am parent, pid: %d\n", getpid());sleep(3);exit(0);}return 0;
}
我们可以看到父进程退出后,子进程的PPID(父进程PID)变为了 1,也就是被init进程领养了
3.3 进程优先级
基本概念:
cpu资源分配的先后顺序,就是指进程的优先权(priority)。
优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性
能。
还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大 改善
系统整体性能。
查看系统进程:
在Linux系统中,用ps -l 命令会输出以下几个类似的内容:
我们可以看到,像UID、PID、PPID、PRI、NI等等
UID:代表执行者身份
PID:代表进程的代号
PPID:代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
PRI :代表这个进程可被执行的优先级,其值越小越早被执行
NI:代表这个进程的nice值
3.3.1 优先级相关 PRI 、NI
PRI可以理解为进程的优先级,它决定了进程被CPU执行的先后顺序,PRI值越小,优先级越高
NI就是nice值,它是进程PRI的修正值,PRI与NI的关系为 PRI(new) = PRI(old) + NI
NI的取值范围为 -20~19(40个级别)
当NI为负数时,PRI就减小,优先级变高,反之更低
在Linux中调整优先级就是调整NI(nice)值,所以NI值可以影响进程PRI从而影响进程的优先级
可以用top指令来修改进程的nice值
语法 : 输入top 回车,然后按r,输入要修改进程的PID回车,而后输入nice值
还有一些其它修改nice值的指令:nice 、renice
默认普通进程静态优先级为 120
普通优先级:100〜139(我们都是普通的优先级,看nice值的取值范围,可与之对应!)
实时优先级:0〜99(不关⼼)
3.3pro 补充进程概念
竞争性:系统进程数⽬众多,⽽CPU资源只有少量,甚⾄1个,所以进程之间是具有竞争属性的。为 了⾼效完成任务,更合理竞争相关资源,便具有了优先级
独⽴性:多进程运⾏,需要独享各种资源,多进程运⾏期间互不⼲扰
并⾏:多个进程在多个CPU下分别,同时进⾏运⾏,这称之为并⾏
并发:多个进程在⼀个CPU下采⽤进程切换的⽅式,在⼀段时间之内,让多个进程都得以推进,称 之为并发
3.4 进程切换
CPU上下文切换:它实际就是任务切换,或叫CPU寄存器切换,当内核决定执行其它任务的时候,它要保存当前运行进程的状态和信息,也就是在CPU寄存器中的信息。这些内容会被保存在任务(进程)自己的堆栈上,⼊栈⼯作完成后就把下⼀个将要运⾏的任务的当前状况从该任务的栈中重新装⼊CPU寄存器, 并开始下⼀个任务的运⾏,这⼀过程就是context switch
如下面两张图(源于互联网)
这是Linux 0.11版本的内核代码
3.4.1 进程O(1)调度队列
在内核中存着进程的调度队列,一个CPU有一个调度队列,↓看代码↓--内核版本Linux2.6.13
都是个人理解,若有不对,请指出
#define MAX_USER_RT_PRIO 100
#define MAX_RT_PRIO MAX_USER_RT_PRIO
#define BITMAP_SIZE ((((MAX_PRIO+1+7)/8)+sizeof(long)-1)/sizeof(long))
#define MAX_PRIO (MAX_RT_PRIO + 40)
//在Linux2.6.13内核中截取的代码struct prio_array {unsigned int nr_active;unsigned long bitmap[BITMAP_SIZE];struct list_head queue[MAX_PRIO];
};typedef struct prio_array prio_array_t;struct runqueue {spinlock_t lock;unsigned long nr_running;
#ifdef CONFIG_SMP
// 基于进程队列平均数量的cpu负载因子unsigned long cpu_load[3];
#endifunsigned long long nr_switches;unsigned long nr_uninterruptible;unsigned long expired_timestamp;unsigned long long timestamp_last_tick;task_t *curr, *idle;struct mm_struct *prev_mm;
/*struct prio_array {unsigned int nr_active;unsigned long bitmap[BITMAP_SIZE];struct list_head queue[MAX_PRIO];
};
*/// active指针指向arrays中的活跃队列// 当前执行队列prio_array_t *active;// expired指针指向arrays中的过期队列// 也就是下一轮才执行的队列prio_array_t *expired;// 两组队列// 调度队列使用轮换策略// 即执行完活跃队列,就执行过期队列// 这时 active指针指向原过期队列// expired指针指向原活跃队列prio_array_t arrays[2];int best_expired_prio;atomic_t nr_iowait;#ifdef CONFIG_SMPstruct sched_domain *sd;/* For active balancing */int active_balance;int push_cpu;task_t *migration_thread;struct list_head migration_queue;
#endif
#ifdef CONFIG_SCHEDSTATS/* latency stats */struct sched_info rq_sched_info;/* sys_sched_yield() stats */unsigned long yld_exp_empty;unsigned long yld_act_empty;unsigned long yld_both_empty;unsigned long yld_cnt;/* schedule() stats */unsigned long sched_switch;unsigned long sched_cnt;unsigned long sched_goidle;/* try_to_wake_up() stats */unsigned long ttwu_cnt;unsigned long ttwu_local;
#endif
};
如果有多个CPU就要考虑进程个数的负载均衡问题
3.4.2 活跃队列与过期队列
每个进程都有相应的时间片,时间片还没结束的进程都会按照优先级放在活跃队列
nr_active:运行状态进程的数量
queue[140]:每一个下标位置都是一个队列,相同优先级的进程按照FIFO规则进⾏排队调度,所以, 数组下标就是优先级!(相同优先级的进程在queue的同一个下标位置,每个位置都是一条队列,有点像链式哈希表)
调度过程:
1. 从0下标开始遍历queue[140]
2. 找到第一个非空队列,该队列一定为目前优先级最高的队列(因为从0优先级开始遍历)
3. 拿到非空队列的第一个进程,开始执行,调度完成
但是O(n)的时间复杂度,还是太低效了,因此Linux设计了 bitmap[5](位图)
bitmap[5]:⼀共140个优先级、140个进程队列,为了提⾼查找⾮空队列的效率,就可以⽤ 5*32个⽐特位表⽰队列是否为空,这样,便可以⼤⼤提⾼查找效率,这样就将时间复杂度优化为O(1)
↓当然少不了好图↓
过期队列与活跃队列一样,过期队列上的进程都是时间片耗尽的进程,在活跃队列处理完后,会对过期队列上进程的时间片重新计算
runqueue查找⼀个最合适调度的进程的时间复杂度为O(1),不随着进程增多⽽导致时间成本增加,这就是Linux的大O(1)进程调度算法
相关文章:
轻松Linux-4.进程概念
屋漏偏逢连夜雨,今天就学Linux 话不多说,展示军火 1.认识冯诺依曼体系 冯诺依曼体系其实并不是什么稀罕的东西,我们生活中的笔记本、服务器、计算机等等大多都遵守冯诺依曼体系 非常经典的一张图 我们所认识的计算机,是由一个个…...
畅游Diffusion数字人(21):基于Wan2.1的音频驱动数字人FantasyTalking
畅游Diffusion数字人(0):专栏文章导航 前言:AI数字人是目前视觉AIGC最有希望大规模落地的场景之一。现阶段的商业工具,如字节的OminiHuman-1(即梦大师版)、快手的可灵对口型,虽然效果不错,但是收费昂贵。而开源解决方案…...
CentOS禁用nouveau驱动
1、验证 nouveau 是否在运行 lsmod | grep nouveau如果命令返回结果,说明 nouveau 驱动正在运行。 2、编辑黑名单文件 通过编辑黑名单配置文件来禁用 nouveau 驱动,这样在系统启动时不会加载它。 vi /etc/modprobe.d/blacklist-nouveau.conf修改以下…...
《Operating System Concepts》阅读笔记:p587-p596
《Operating System Concepts》学习第 52 天,p587-p596 总结,总计 10 页。 一、技术总结 1.Recovery (1)consistency checking consistency checking 工具:fsck。 (2)log-structure file system (3)WAFL file system 2.Veritas (1)Ve…...
k8s 1.24.17版本部署(使用Flannel插件)
1.k8s集群环境准备 推荐阅读: https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/ 1.1 环境准备 环境准备:硬件配置: 2core 4GB磁盘: 50GB操作系统: Ubuntu 22.04.04 LTSIP和主机名:10.0.0.231 master23110.0.0.232 worker23210.0…...
通信协议详解(十):PSI5 —— 汽车安全传感器的“抗干扰狙击手”
一、PSI5是什么? 一句话秒懂 PSI5就像传感器界的“防弹信使”:在汽车安全系统(如气囊)中,用两根线同时完成供电数据传输,即便车祸时线路受损,仍能确保关键信号准确送达! 基础概念…...
Kafka生产者和消费者:数据管道的核心引擎与智能终端
在分布式系统中,数据的高效流动如同人体的血液循环,而Kafka的生产者(Producer)与消费者(Consumer)正是驱动这一循环的核心组件。它们不仅是Kafka客户端的基本形态,更是构建实时数据生态的基石。…...
特权FPGA之按键消抖
完整代码如下所示: timescale 1ns / 1ps// Company: // Engineer: 特权 // // Create Date: // Design Name: // Module Name: // Project Name: // Target Device: // Tool versions: // Description: // // Dependencies: // // Revision: // …...
实时比分更新系统的搭建
搭建一个实时比分更新系统需要考虑多个技术环节,以下是一个完整的实现方案: 一、系统架构 1.数据获取层 比分数据API接入(如熊猫比分、API-Football等) 网络爬虫(作为备用数据源) 2.数据处理层 …...
【Linux】线程的概念与控制
目录 1. 整体学习思维导图 2. 线程的概念 2.1 基础概念 2.2 Linux下的线程 初步理解: 2. 分页式存储 3.1 页表 3.1.1 页框/页 3.1.2 页表机制 3.1.3 从虚拟地址到物理地址的转换 总结: 3.2 TLB快表 3.3 缺页异常(Page Fault&am…...
K8s 老鸟的配置管理避雷手册
Yining, China 引言 对于这种案例,你们的处理思路是怎么样的呢,是否真正的处理过,如果遇到,你们应该怎么处理。 最后有相关的学习群,有兴趣可以加入。 开始 一、血泪教训:环境变量引发的真实灾难 1.1 …...
飞速(FS)解决方案验证实验室搬迁升级,赋能客户技术服务
飞速(FS)解决方案验证实验室近日顺利完成搬迁升级,标志着飞速(FS)在解决方案可行性验证、质量保障以及定制化需求支持方面迈上新台阶,进一步提升了产品竞争力和客户信任度。 全新升级的实验室定位为技术验证…...
柔性关节双臂机器人奇异摄动鲁棒自适应PD控制
1 双臂机器人动力学模型 对于一个具有多个关节的机器人来说,机器人端动力学子方程及关节驱动电机端动力学子方程为: 以上为推导过程,MATLAB程序已完成,若需要可找我。...
遵循IEC62304YY/T0664:确保医疗器械软件生命周期合规性
一、EC 62304与YY/T 0664的核心定位与关系 IEC 62304(IEC 62304)是国际通用的医疗器械软件生命周期管理标准,适用于所有包含软件的医疗器械(如嵌入式软件、独立软件、移动应用等),其核心目标是确保软件的安…...
Kafka和RocketMQ相比有什么区别?那个更好用?
Kafka和RocketMQ相比有什么区别?那个更好用? Kafka 和 RocketMQ 都是广泛使用的消息队列系统,它们有很多相似之处,但也有一些关键的区别。具体选择哪个更好用,要根据你的应用场景和需求来决定。以下是它们之间的主要区别: 1. …...
空对象模式(Null Object Pattern)在C#中的实现详解
一 、什么是空对象模式 空对象模模是靠”空对孔象式是书丯一种引施丼文行为,行凌,凌万成,个默疤"空象象象象来飞䛿引用用用用电从延盈盈甘仙丿引用用用职从延务在仅代砷易行行 」这种燕式亲如要目的片片 也说媚平父如如 核心思烟 定义一个人 派一个 � 创建…...
【Windows】Win2008服务器SQL服务监控重启脚本
以下是一个用于监控并自动重启 SQL Server 服务的批处理脚本,适用于 Windows Server 2008 和 SQL Server 2012(默认实例): echo off setlocal enabledelayedexpansion:: 配置参数 set SERVICE_NAMEMSSQLSERVER set LOG_FILEC:\SQ…...
Spring MVC 操作会话属性详解(@SessionAttributes 与 @SessionAttribute)
Spring MVC 操作会话属性详解(SessionAttributes 与 SessionAttribute) 1. 核心注解对比 注解作用范围功能SessionAttributes类级别声明控制器中需要持久化的模型属性(存入 HttpSession)SessionAttribute方法参数/返回值显式绑定…...
416. 分割等和子集
416. 分割等和子集 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 示例 1: 输入:nums [1,5,11,5] 输出:true 解释:数组可以分割成 [1, 5, 5] 和…...
Composer安装Laravel步骤
Composer安装Laravel步骤 要使用 Composer 安装 Laravel,请按照以下步骤操作: 确保已经安装了 Composer。如果还没有安装,请访问 https://getcomposer.org/download/ 下载并安装。 打开命令行或终端。 使用 cd 命令导航到你的项目目录&…...
游戏引擎学习第209天
调整椅子α 昨天,我们实现了将数据输出到调试流中的功能,之前的调试流大多只包含性能分析数据,而现在我们可以将任意数据放入调试流中。 完成这个功能后,我们接下来要做的是收集这些数据并显示出来,这样我们就能有一…...
更新vscode后链接远程服务器出现了报错‘无法建立连接:远程主机不满足运行vscode服务器的先决条件’20250408
更新了vscode之后再链接远程服务器出现了报错,如下: 1. 确认服务器上的库版本 1.1 检查 glibc 版本 在服务器终端运行: ldd --version 最低要求:VS Code 远程开发需要 glibc ≥ 2.28。 1.2 检查 libstdc 版本 在服务器终端运…...
电磁兼容特种测试
并非所有的检测都能在实验室的标准场地中完成。今天,就带大家走进电磁兼容特种测试中需要现场测试的情况,看看哪些场合和设备有着特殊的测试需求。 哪种场合需要现场测试? 大型设备由于物理尺寸或供电功率上的限制,无法在一般…...
PyTorch 基础要点详解:从模型构建到评估
在深度学习领域,PyTorch 作为一款广受欢迎的开源框架,为开发者提供了便捷高效的工具。今天,我们就深入探讨一下 PyTorch 中的几个关键要点:torch.nn.Linear、torch.nn.MSELoss、model.train() 以及 model.eval(),了解它…...
Dockerfile中CMD命令未生效
今天在使用dockerfile构建容器镜像时,最后一步用到CMD命令启动start.sh,但是尝试几遍都未能成功执行脚本。最后查阅得知:Dockerfile中可以有多个cmd指令,但只有最后一个生效,CMD会被docker run之后的参数替换。 CMD会…...
Linux平台MQTT测试抓包分析
Linux平台搭建MQTT测试环境-CSDN博客基于这里的测试代码抓包 sudo tcpdump -i any -w mqtt1.cap 上述源码中 tcp://localhost:1883 配置连接: Broker Address: localhostPort: 1883 整体通信流程 1. Subscriber和Broker(代理服务器)建立…...
Docker全方位指南
目录 前言 第一部分:Docker基础与安装 1.1 什么是Docker? 1.2 Docker的适用场景 1.3 全平台安装指南 1.4 配置优化 第二部分:Docker核心操作与原理 2.1 镜像管理 2.2 容器生命周期 2.3 网络模型 2.4 Docker Compose 第三部分&…...
【经典DP】三步问题 / 整数拆分 / 不同路径II / 过河卒 / 下降路径最小和 / 地下城游戏
⭐️个人主页:小羊 ⭐️所属专栏:动态规划 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 动态规划总结Fibonacci数列BC140 杨辉三角杨辉三角三步问题最小花费爬楼梯孩子们的游戏解码方法整数拆分不同路径不同路径II过…...
Koji/OBS编译节点OS版本及工具版本管理深度实践指南
引言 在分布式编译框架Koji/OBS中,有效管理编译节点的操作系统(OS)版本及工具版本是确保构建环境稳定性、兼容性和安全性的关键。本文将从多版本共存、自动化更新、兼容性管理等多个维度,系统阐述如何高效管理编译节点的OS版本及…...
39、web前端开发之Vue3保姆教程(三)
四、Vue3中集成Element Plus 1、什么是Element Plus Element Plus 是一款基于 Vue 3 的开源 UI 组件库,旨在为开发者提供一套高质量、易用的组件,用于快速构建现代化的 web 应用程序。 Element Plus 提供了大量的 UI 组件,包括但不限于: 表单组件:输入框、选择器、开关…...
多类型医疗自助终端智能化升级路径(代码版.下)
医疗人机交互层技术实施方案 一、多模态交互体系 1. 医疗语音识别引擎 # 基于Wav2Vec2的医疗ASR系统 from transformers import Wav2Vec2Processor, Wav2Vec2ForCTC import torchaudioclass MedicalASR:def __init__(self):self.processor = Wav2Vec2Processor.from_pretrai…...
Git代码管理
这里写目录标题 分支管理策略TrunkBased🌱 核心理念✅优点❌缺点适用场景 GitFlow✅ GitFlow 的优点❌ GitFlow 的缺点适用场景 AOneFlow✅ AOneFlow 的优点❌缺点适用场景 如何选择分支策略?代码提交规范🌱分支管理🔄代码更新⚔️…...
CubeMX配置STM32F103PWM连续频率输出
要求: 输出2-573Hz频率,输出频率步长小于1Hz 一、CubeMX配置 auto-reload preload在下个周期加载ARR Output compare preload 在下个周期加载CCR 二、 程序 1.启动PWM输出 HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1); 2.根据频率调整PSC、ARR、…...
举例说明计算机视觉(CV)技术的优势和挑战。
计算机视觉(CV)技术是人工智能领域的一个重要分支,通过让计算机“看”和“理解”图像或视频,可以实现许多实际应用。以下是计算机视觉技术的优势和挑战的例子: 优势: 自动化处理:CV技术可以自动化地处理大量图像或视频数据,实现快速而准确的分析和识别。提高效率:在许…...
工程师 - FTDI SPI converter
中国网站:FTDIChip- 首页 UMFT4222EV-D UMFT4222EV-D - FTDI 可以下载Datasheet。 UMFT4222EVUSB2.0 to QuadSPI/I2C Bridge Development Module Future Technology Devices International Ltd. The UMFT4222EV is a development module which uses FTDI’s FT4222H…...
河畔石上数(C++)
在 C 里,std::set 是标准模板库(STL)提供的一种关联容器,它能高效地存储唯一元素,并且元素会按照特定的顺序排列,默认是升序。下面从多个方面为你详细介绍 std::set。 1. 头文件包含 若要使用 std::set&a…...
《线性表、顺序表与链表》教案(C语言版本)
🌟 各位看官好,我是maomi_9526! 🌍 种一棵树最好是十年前,其次是现在! 🚀 今天来学习C语言的相关知识。 👍 如果觉得这篇文章有帮助,欢迎您一键三连,分享给更…...
【用Cursor 进行Coding 】
「我」:“添加 XXX 功能” [Claude-3.7]:“好的,我完成了,还顺手做了 19个你没要求不需要的功能、甚至还修改了原有999行正常代码 ~ 不用谢” [Gemini-2.5]:“好的,我会…...
vue2 打包时增加时间戳防止浏览器缓存,打包后文件进行 js、css 压缩
文章目录 前言一、什么是浏览器缓存二、展示效果三、vue.config.js 代码四、代码压缩部分服务器不支持五、感谢 前言 vue 开发过程中,项目前端代码需要更新,更新后由于浏览器缓存导致代码没有及时更新所产生错误,所以在打包时增加时间戳防止…...
TIM定时器
一、TIM定时器 STM32高级定时器实战:PWM、捕获与死区控制详解-CSDN博客 二、相关函数 1.TIM_TimeBaseInitTypeDef结构体讲解 typedef struct {uint16_t TIM_Prescaler; // 预分频器,用于设置定时器计数频率uint16_t TIM_CounterMode; /…...
S130N-ISI 全栈方案与云平台深度协同:重构 PLC 开发新范式
一、什么是 PLC? 1.技术定义 PLC(Power Line Communication)是一种创新的通信技术,它以电力线作为天然的传输介质,通过先进的信号调制技术将高频数据信号叠加于工频电流之上,实现电力输送与数据通信的双频共…...
Jenkins 插件文件优先使用 .jpi 后缀
.hpi 和 .jpi 文件本质上是 Jenkins 插件的打包格式,两者的区别主要体现在历史和命名习惯上: ✅ .hpi(Hudson Plugin) 来源:最初是 Hudson 项目的插件格式。含义:Hudson Plugin 的缩写。用途:早…...
# 决策树与PCA降维在电信客户流失预测中的应用
决策树与PCA降维在电信客户流失预测中的应用 在数据分析和机器学习领域,电信客户流失预测是一个经典的案例。本文将通过Python代码实现,探讨决策树模型在电信客户流失预测中的应用,并结合PCA降维技术优化模型性能,同时对比降维前…...
go语言的语法糖以及和Java的区别
1. Go 语言的语法糖及简化语法 Go 语言本身设计理念是简洁、清晰,虽然不像某些动态语言那样“花哨”,但它提供了几种便捷语法,使代码更简洁: 1.1 短变量声明(Short Variable Declaration) 语法࿱…...
WebRtc 视频流卡顿黑屏解决方案
// node webrtc视频转码服务 const url "http://10.169.xx.xx:8000" <video :ref"videoRefs${index}" :id"videoRefs4_${index}" :src"item" controls:key"item" autoplay muted click"preventDefaultClick"…...
信息安全测评中心-国产化!
项目上使用产品,必须通过国家信息安全测评/ 信息技术产品安全测评,有这个需求的话,可以到CN信息安全测评中心官网中的--测评公告一栏中,找符合要求的产品。 测评公告展示的包括硬件产品、系统、服务资质等。 网址及路径…...
MySQL学习笔记九
第十一章使用数据处理函数 11.1函数 SQL支持函数来处理数据但是函数的可移植性没有SQL强。 11.2使用函数 11.2.1文本处理函数 输入: SELECT vend_name,UPPER(vend_name) AS vend_name_upcase FROM vendors ORDER BY vend_name; 输出: 说明&#…...
DFS 蓝桥杯
最大数字 问题描述 给定一个正整数 NN 。你可以对 NN 的任意一位数字执行任意次以下 2 种操 作: 将该位数字加 1 。如果该位数字已经是 9 , 加 1 之后变成 0 。 将该位数字减 1 。如果该位数字已经是 0 , 减 1 之后变成 9 。 你现在总共可以执行 1 号操作不超过 A…...
动态规划dp专题-(上)
目录 dp理论知识🔥🔥 🎯一、线性DP (1)🚀斐波那契数 -入门级 (2)🚀898. 数字三角形-acwing ---入门级 (3)往期题目 ①选数异或:在…...
正则表达式(一)
一、模式(Patterns)和修饰符(flags) 通过正则表达式,我们可以在文本中进行搜索和替换操作,也可以和字符串方法结合使用。 正则表达式 正则表达式(可叫作 “regexp”,或 “reg”&…...