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

【Linux篇】进程控制

📌 个人主页: 孙同学_
🔧 文章专栏:Liunx
💡 关注我,分享经验,助你少走弯路!
在这里插入图片描述

1. 进程创建

1.1 fork函数

linuxfork函数是非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。

#include <unistd.h>
pid_t fork(void);
返回值:⾃进程中返回0,⽗进程返回⼦进程id,出错返回-1

进程调用fork,当控制转移到内核中的fork代码后,内核做:

  • 分配新的内存块和内核数据结构给子进程
  • 将父进程部分数据结构内容拷贝至子进程
  • 添加子进程到系统进程列表当中
  • fork返回,开始调度器调度
    在这里插入图片描述
    当一个进程调用fork之后,就有两个二进制代码相同的进程。而且它们都运行到相同的地方。但每个进程都将可以开始它们自己的旅程,看如下程序。
int main( void )
{pid_t pid;printf("Before: pid is %d\n", getpid());if ( (pid=fork()) == -1 )perror("fork()"),exit(1);printf("After:pid is %d, fork return %d\n", getpid(), pid);sleep(1);return 0;
} 
运⾏结果:
[root@localhost linux]# ./a.out
Before: pid is 43676
After:pid is 43676, fork return 43677
After:pid is 43677, fork return 0

这里看到了三行输出,一行before,两行after。进程43676先打印before消息,然后它有打印after。另一个after消息有43677打印的。注意到进程43677没有打印before,为什么呢?如下图所示
在这里插入图片描述
所以,fork之前父进程独立执行,fork之后,父子两个执行流分别执行。
注意fork之后,谁先执行完全由调度器决定。

1.2 写时拷贝

通常,父子代码共享,父子再不写入时,数据也是共享的,当任意一方试图写入,便以写时拷备的方式各自一份副本。具体见下图:
在这里插入图片描述
上图显示父进程代码段在自己的页表中是只读的,包括我们以前定义的字符常量区,代码是不可写的,可是数据段为什么也是只读的?起始在我们的父进程还没创建子进程前,代码段是只读的没问题,但是数据段对应的映射关系,可能有一百个一千个映射地址,这些映射地址的权限实际上是读写的,但一旦创建了子进程,操作系统就会把数据段的权限也改成只读的。 然后后面的父子进程,比如说子进程尝试对它的数据进行写入,当它写入时,操作系统就会发现你要访问的数据,第一,数据是合法的,因为虚拟地址物理地址都有,而且它发现访问的区域是数据段,如果是代码段肯定在start_code,end_code这个区间里面,如果是数据段肯定在start_data,start_end这个区间里面,发现你是数据段,而且页表的映射关系是正确的,但是发现数据段怎么是只读的,所以这时候操作系统就会出错,这种出错不是真的错了,是操作系统检测到一个用户对一个只读的区域进行写入,但操作系统经过检查发现它是数据段,而且是子进程,这时候操作系统就会触发写时拷贝。写时拷贝是通过设置页表的权限,让页表让操作系统出错的行为。让操作系统知道我们正在访问一个只读的区域,进而在错误的驱使之下让操作系统完成对应的写时拷贝这样的任务。

因为有写时拷贝技术的存在,所以父子进程得以彻底分离离!完成了进程独立性的技术保证!
写时拷贝,是一种延时申请技术,可以提高整机内存的使用率

为什么要写时拷贝?

  1. 减少子进程的创建时间
  2. 减少内存浪费

1.3 fork调用失败的原因

  • 系统中有太多的进程
  • 实际用户的进程数超过了限制

2. 进程终止

进程终止的本质是释放系统资源,就是释放进程申请的相关内核数据结构和对应的数据和代码。

2.1 进程退出场景

  1. 代码运行完毕,结果正确
  2. 代码运行完毕,结果不正确
  3. 代码异常终止(退出码无意义)

2.2 进程常见退出方式

正常终止(可以通过 echo $? 查看最近进程的退出码):

  1. main返回(main函数结束表示进程结束,其他函数只表示自己函数调用完成)
  2. 调用exit(status)(任何地方调用exit表示进程结束,并返回给父进程bash子进程的退出码)
  3. _exit:终止一个调用进程(相当于谁调用它,它把谁“弄死”)
2.2.1 exit函数
#include <unistd.h>
void exit(int status);

exit最后也会调用_exit,但在调用_exit之前,还做了其他工作:

  1. 执行用户通过atexiton_exit定义的清理函数。
  2. 关闭所有打开的流,所有的缓存数据均被写入
  3. 调用_exit
    在这里插入图片描述
2.2.2 _exit函数
#include <unistd.h>
void _exit(int status);
参数:status 定义了进程的终⽌状态,⽗进程通过wait来获取该值

说明:虽然statusint,但是仅有低8位可以被父进程所用。所以_exit(-1)时,在终端执行$?发现返回值是255。

2.2.3 exit和_exit的区别:

exit是c语言提供的,_exit是系统提供的
进程如果exit退出的时候,exit()会进行缓冲区的刷新
进程如果exit退出的时候,_exit不会进行缓冲区的刷新

库函数和系统调用是上下层的关系,库函数没有进程终止能力,只能调用系统调用,操作系统给它提供的进程终止的接口它才能终止进程,所以exit的底层封装了_exit,所以我们之前谈论的缓冲区一定不在操作系统的内部,而是库缓冲区(c语言提供的缓冲区)

异常退出

  • ctrl + c,信号终止
2.2.4 退出码

退出码在Linux中通常用来表示命令执行后的结果,0表示成功,非0表示不同的错误类型
Linux Shell 中的主要退出码:

退出码说明
0成功(命令正常执行)
1一般性错误(如参数错误、文件未找到、权限不足等)
2Shell 内置命令误用(如语法错误、未找到命令等)
126权限问题(命令不可执行,如缺少执行权限)
127命令未找到(Shell 找不到指定命令)
130进程被 Ctrl+C 终止(SIGINT 信号)
141进程被 SIGHUP 信号终止(如终端关闭)

3. 进程等待

3.1 进程等待必要性

  • 之前讲过,子进程退出,父进程如果不管不顾,就可能造成僵尸进程的问题,进而造成内存泄漏。
  • 进程一旦变成僵尸状态,那就刀枪不入,“杀人不眨眼”的kill-9也无能为力,因为谁也没有办法杀死一个已经死去的进程。
  • 最后,父进程派给子进程的任务完成的如何,我们需要知道。如,子进程运行完成,结果对还是不对,或者是否正常退出。
  • 父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息

3.2 进程等待的方法

3.2.1 wait方法

如果等待子进程,子进程没有退出,父进程就会阻塞在wait调用处(相当于scanf)
在这里插入图片描述

在这里插入图片描述

#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int* status);
返回值:成功返回被等待进程pid,失败返回-1。
参数:输出型参数,获取子进程退出状态,不关⼼则可以设置成为NULL
3.2.2 waitpid方法
pid_ t waitpid(pid_t pid, int *status, int options);
返回值:当正常返回的时候waitpid返回收集到的子进程的进程ID;如果设置了选项WNOHANG,⽽调⽤中waitpid发现没有已退出的子进程可收集,则返回0;如果调⽤中出错,则返回-1,这时errno会被设置成相应的值以指⽰错误所在;
参数:pid:Pid = -1,等待任⼀个子进程。与wait等效。Pid > 0.等待其进程ID与pid相等的⼦进程。status: 输出型参数WIFEXITED(status): 若为正常终⽌子进程返回的状态,则为真。(查看进程是否是正常退出)WEXITSTATUS(status)((status>>8)&0xFF): 若WIFEXITED⾮零,提取子进程退出码。(查看进程的退出码)options:默认为0,表⽰阻塞等待WNOHANG: 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等
待。若正常结束,则返回该子进程的ID。
  • 如果子进程已经退出,调用wait/waitpid时,wait/waitpid会立即返回,并且释放资源,获得子进程退出信息。
  • 如果在任意时刻调用wait/waitpid,子进程存在且正常运行,则进程可能阻塞。
  • 如果不存在该子进程,则立即出错返回。
    在这里插入图片描述
3.2.3 获取子进程status
  • waitwaitpid,都有一个status参数,该参数是一个输出型参数,由操作系统填充。
  • 如果传递NULL,表示不关心子进程的退出状态信息。
  • 否则,操作系统会根据该参数,将子进程的退出信息反馈给父进程。
  • status不能简单的当作整形来看待,可以当作位图来看待,具体细节如下图(只研究status低16比特位):
    在这里插入图片描述
3.2.4 阻塞与非阻塞等待
  • 进程的阻塞等待方式:
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(void)
{pid_t pid;if ((pid = fork()) == -1)perror("fork"), exit(1);if (pid == 0) {sleep(20);exit(10);}else {int st;int ret = wait(&st);if (ret > 0 && (st & 0X7F) == 0) { // 正常退出 printf("child exit code:%d\n", (st >> 8) & 0XFF);}else if (ret > 0) { // 异常退出 printf("sig code : %d\n", st & 0X7F);}}
}
测试结果:
# ./a.out #等20秒退出
child exit code : 10
# ./a.out #在其他终端kill掉
sig code : 9
  • 进程的非阻塞等待方式:
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <vector>
typedef void (*handler_t)(); // 函数指针类型 
std::vector<handler_t> handlers; // 函数指针数组 
void fun_one() {printf("这是⼀个临时任务1\n");
}
void fun_two() {printf("这是⼀个临时任务2\n");
}
void Load() {handlers.push_back(fun_one);handlers.push_back(fun_two);
}
void handler() {if (handlers.empty())Load();for (auto iter : handlers)iter();
}
int main() {pid_t pid;pid = fork();if (pid < 0) {printf("%s fork error\n", __FUNCTION__);return 1;}else if (pid == 0) { // childprintf("child is run, pid is : %d\n", getpid());sleep(5);exit(1);}else {int status = 0;pid_t ret = 0;do {ret = waitpid(-1, &status, WNOHANG); // ⾮阻塞式等待 if (ret == 0) {printf("child is running\n");}handler();} while (ret == 0);if (WIFEXITED(status) && ret == pid) {printf("wait child 5s success, child return code is :%d.\n",WEXITSTATUS(status));}else {printf("wait child failed, return.\n");return 1;}}return 0;
}

4. 进程替换

我们先来看一段代码:
在这里插入图片描述
在这里插入图片描述
上面这种现象就叫做程序替换,也就是我自己的程序把系统当中的指令跑起来了。在程序替换的时候,并没有创建新的进程,只是把当前进程的代码和数据用新的进程的代码和数据覆盖式的进行替换。

  1. 问题一:“为什么我的程序运行结束了”,这段话没有在显示器上打印出来?
    答案是一旦程序替换成功就去执行新代码了,原始代码的后半部分已经不存在了
  • 有没有办法让后面的代码能继续执行?
    答案是有的,创建一个子进程,让子进程去做替换工作,让父进程继续执行后面的代码。
    在这里插入图片描述
    效果演示:
    在这里插入图片描述
    📌Tips:程序替换也能替换我们自己写的程序,就相当于一种加载器,可以加载各种程序,包括编译型的解释型的,程序替换本质上不会创建新的进程
    为什么不会影响父进程呢?
    a.进程具有独立性 b.数据和代码发生写时拷贝
  1. execl的返回值
    在这里插入图片描述
    execl函数只有失败返回值,没有成功返回值
    💦结论exec*系列的函数,不用做返回值判定,只要返回,就是失败

4.1 替换原理

在这里插入图片描述

4.2 替换函数

  1. int execl(const char *path,const char *arg,...),第一个参数表示程序+路径名,第二个参数有个口诀:命令行怎么写,我们就怎么传(当然传-al也是可以的),而把参数一个一个的传进来我们称之为list,类似于以链表的形式传给它,所以execl这个l就是llist的意思,execl函数的最后一个参数必须以NULL结尾,表明参数传递完成在这里插入图片描述

  2. int execlp(const char *file,cont char *arg,...),execlp当中的p表示PATH,所以第一个参数只需传要执行的程序名就行了,因为execlp会自动的在环境变量(PATH)里查找对应的命令,所以execlp一般执行系统级的命令。后面参数的传递和上面的相同
    在这里插入图片描述

  3. int execv(const char *path,char *const argv[]),首先它没有带p所以它的参数是path,所以同上上,这里的v就相当于vector,所以第二个参数就以数组的形式呈现了,所以就必须提供一个命令行参数表,就是指针数组,就是把ls -a -l整体放在数组里,一次性传递,这个表也必须以NULL结尾。所以我们以前执行的所有命令行参数都是父进程通过execv传给子进程的
    在这里插入图片描述

  4. int execvp(const char *path,char *const argv[]),有p所以不用带路径
    在这里插入图片描述

  5. int execvpe(const *file,char *const argv[],char *const envp[])这里的v表示以数组的方式传进来,p表示不用带路径,e表示环境变量,如果非要传递环境变量列表,要求:被替换的子进程使用全新的Env列表(自己写的)
    在这里插入图片描述
    若要以新增的方式传递环境列表呢?
    putenv表示哪个进程调用它,就在谁的环境变量表里新增一个环境变量(B是A的子进程,C是B的子进程,如果B在它的环境列表里导入了一个新的环境变量,A的环境列表里看不到,而C的环境列表里能看到)
    ➁如果我们就行用execvpe的方式呢?environ
    在这里插入图片描述
    表示把新增的环境变量添加到环境变量表里面去,然后把环境变量表的起始地址传给execvpe

  6. int execle(const *path,const *arg,...,char * const envp[])
    在这里插入图片描述

总结:
这些函数原型看起来很容易混,但只要掌握了规律就很好记。

  • l(list):表示参数采用列表
  • v(vector):参数用数组
  • p(path):有p自动搜索环境变量PATH
  • e(env):表示自己维护环境变量
    在这里插入图片描述

上面这些函数都是对系统调用进行了语言型的封装,最后都要调用系统调用execve,为什么要做语言封装呢?因为程序替换时要面对各种各样上层替换的场景。所以execve在man手册第2节
在这里插入图片描述
下图exec函数簇一个完整的例子:
在这里插入图片描述


👍 如果对你有帮助,欢迎:

  • 点赞 ⭐️
  • 收藏 📌
  • 关注 🔔

相关文章:

【Linux篇】进程控制

&#x1f4cc; 个人主页&#xff1a; 孙同学_ &#x1f527; 文章专栏&#xff1a;Liunx &#x1f4a1; 关注我&#xff0c;分享经验&#xff0c;助你少走弯路&#xff01; 1. 进程创建 1.1 fork函数 在linux中fork函数是非常重要的函数&#xff0c;它从已存在进程中创建一个…...

freeswitch(在呼叫失败的情况下如何播放语⾳提⽰)

亲测版本centos 7.9系统–》 freeswitch1.10.9 本人freeswitch安装路径(根据自己的路径进入) /usr/local/freeswitch/etc/freeswitch⼀般我们在打电话时会听到『您拨的电话正在通话中,请稍后再 拨.』,或『电话⽆应答』之类的提⽰,我们在 FreeSWITCH ⾥也可以这样做。 …...

软考系统架构设计师之计算机组成与体系结构笔记

一、计算机硬件组成 1. 冯诺依曼结构与哈佛结构 冯诺依曼结构&#xff1a;以存储器为中心&#xff0c;指令和数据统一存储&#xff0c;通过总线连接运算器、控制器、输入输出设备。其核心思想是“存储程序控制”&#xff0c;但存在存储器访问瓶颈问题。哈佛结构&#xff1a;指…...

gonet开源游戏服务器环境配置

1.mysql搭建 搜索mysql-server apt安装包名 sudo apt search mysql-server 安装mysql-server sudo apt-get install mysql-server 安装完成后会&#xff0c;启动mysql服务及创建系统服务 查看服务状态 systemctl status mysql.service 使用超级权限登陆mysql sudo mysql 授…...

软件工程之软件验证计划Software Verification Plan

个人主页&#xff1a;云纳星辰怀自在 座右铭&#xff1a;“所谓坚持&#xff0c;就是觉得还有希望&#xff01;” 本文为基于ISO26262软件验证计划模板&#xff0c;仅供参考。 软件验证计划&#xff0c;包括&#xff1a; 1. 软件需求验证计划 2. 软件架构设计验证计划 3. 软件单…...

大模型详细配置

Transformer结构 目前主力大模型都是基于Transformer的&#xff0c;以下是Transformer的具体架构 它由编码器(Encoder)以及解码器(Decoder)组成&#xff0c;前者主要负责对输入数据进行理解&#xff0c;将每个输入 词元都编码成一个上下文语义相关的表示向量&#xff1b;后者…...

Web爬虫利器FireCrawl:全方位助力AI训练与高效数据抓取

Web爬虫利器FireCrawl&#xff1a;全方位助力AI训练与高效数据抓取 一、FireCrawl 项目简介二、主要功能三、FireCrawl应用场景1. 大语言模型训练2. 检索增强生成&#xff08;RAG&#xff09;&#xff1a;3. 数据驱动的开发项目4. SEO 与内容优化5. 在线服务与工具集成 四、安装…...

产业观察:ASML2025.3.21

一.发展历程 1.1 创业背景 在半导体行业的快速发展背景下&#xff0c;ASML的创业故事拉开了帷幕。1983年&#xff0c; 飞利浦S&I技术总监Georg de Kruyff 与 ASM创始人Arthur del Prado 重启合作讨论&#xff0c;为ASML的创立奠定了基础。双方迅速达成协议&#xff0c;计…...

go语言学习教程推荐,零基础到做项目

一、基础入门阶段 官方教程&#xff08;免费&#xff09; • A Tour of Go&#xff1a;交互式入门教程&#xff0c;边学边练 • Go by Example&#xff1a;通过300代码片段学习语法 入门书籍 • &#x1f4d8;《Go语言圣经》中文版&#xff08;免费在线阅读&#xff09;&#…...

设计模式 二、创建型设计模式

GoF是 “Gang of Four”&#xff08;四人帮&#xff09;的简称&#xff0c;它们是指4位著名的计算机科学家&#xff1a;Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides。他们合作编写了一本非常著名的关于设计模式的书籍《Design Patterns: Elements of Reusable…...

51c大模型~合集73

我自己的原文哦~ https://blog.51cto.com/whaosoft/12318419 #Emu3 视频、图像、文本&#xff0c;只需基于下一个Token预测&#xff1a;智源Emu3发布&#xff0c;验证多模态模型新范式 OpenAI 前首席科学家、联合创始人 Ilya Sutskever 曾在多个场合表达观点&#xff1…...

【el-upload】el-upload组件 - list-type=“picture“ 时,文件预览展示优化

目录 问题图el-upload预览组件 PicturePreview效果展示 问题图 el-upload <el-uploadref"upload"multipledragaction"#":auto-upload"false":file-list"fileList"name"files":accept".png,.jpg,.jpeg,.JGP,.JPEG,.…...

STM32F103系列配置中断向量表偏移(Keil/STM32CubeIDE)

需要在flash中添加bootloader的话&#xff0c;需要对flash进行分区&#xff0c;即bootloader区和app区(程序运行区)&#xff0c;主要记录在 Keil 平台和 STM32CubeIDE平台 上的中断向量表偏移配置&#xff0c;以偏移 0x2800 为例&#xff0c;即预留10k大小的空间给bootloader …...

Redis常用数据类型和使用常见以及基本操作举例(适合初学者,以医药连锁管理系统为背景)

Redis的常见数据类型&#xff0c;包括String、Hash、List、Set、Zset等&#xff0c;这些数据类型都有各自的特点和适用场景。接下来&#xff0c;将这些数据类型与医药连锁管理系统的业务场景进行匹配。 String类型&#xff0c;适合存储单个值。在医药连锁管理系统中&#xff0…...

ASL扩展坞方案|Type-c转换器方案|ASL原厂代理商

安格瑞科技代理的ASL主板组件系列包括CS5211、CS5311、CS5232、CS5263、CS621x、CS5523、CS5518等产品&#xff1b; CS5228ANDP to HDMI(4K60HZ)CS5262ANDP (4lanes) to HDMI2.0 4k60Hz VGACS5263ANDP(4lanes) to HDMI2.0 4k60HzCS5363ANDP (4lanes) to HDMI2.0 4k60Hz CS521…...

论文略读(2025.3.18-更新中)

关于可控视频生成 I2V3D: Controllable image-to-video generation with 3D guidance Image to Video工作&#xff0c;能够实现给一张图&#xff0c;输出一个视频&#xff0c;且可以控制相机。动态信息来自于用户手工设计&#xff08;相机移动&#xff0c;人体骨骼驱动&#x…...

基于SpringBoot的“校园招聘网站”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“校园招聘网站”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统整体功能图 局部E-R图 系统首页界面 系统注册…...

【Linux进程七】程序地址空间

【Linux进程七】程序地址空间 1.进程的地址空间分布2.类型的本质是偏移量3.什么是进程地址空间4.页表的映射和访问权限字段5.地址空间的作用 1.进程的地址空间分布 堆是向上扩展的&#xff0c;栈是向下扩展的 因为字符常量区和代码区相邻&#xff0c;受到同样的保护&#xff0c…...

Linux C/C++编程——线程

线程是允许应用程序并发执行多个任务的一种机制&#xff0c;线程参与系统调度。 系统调度的最小单元是线程、而并非进程。 线程包含在进程之中&#xff0c;是进程中的实际运行单位。一个线程指的是进程中一个单一顺序的控制流&#xff08;或者说是执行路线、执行流&#xff09;…...

【Spring Boot 中 `@Value` 注解的使用】

文章目录 一、前言二、Value 注解简介三、Value 注解的常见用法1. 读取 application.properties 或 application.yml 配置值&#xff08;1&#xff09;配置文件示例&#xff08;2&#xff09;Java 代码示例&#xff08;3&#xff09;测试输出 2. 使用 Value 设置默认值3. 读取系…...

【CAD二次开发】调试无法进入断点提示无可用源问题(非空心断点)

问题截图&#xff1a;显示无可用源&#xff0c;关闭后F5走完后&#xff0c;启动的调试就中断了 操作是&#xff1a;打开Cad&#xff0c;打开dwg后&#xff0c;执行命令&#xff0c;就出现以上截图问题。 问题来源&#xff1a;通常是由于 AutoCAD 的 纤程模式&#xff08;Fiber&…...

Ubuntu下Docker部署Misskey:打造你的去中心化社交平台

引言 在信息爆炸的时代&#xff0c;人们对于社交平台的需求日益增长&#xff0c;同时也更加注重数据的隐私和自由。Misskey作为一个开源的去中心化社交平台&#xff0c;为用户提供了一个全新的选择。本文将详细介绍如何在Ubuntu Linux环境下&#xff0c;利用Docker快速部署Mis…...

【Vue3】01-vue3的基础 + ref reactive

首先确保已经有了ES6的基础 本文介绍 vue 的基础使用以及 两种响应数据的方式。 目录 1. 创建一个vue应用程序 2. Vue模块化开发 3. ref 和 reactive 的区别 1. 创建一个vue应用程序 所需的两个文件&#xff1a; https://unpkg.com/vue3/dist/vue.global.js https://un…...

C++实现rabbitmq生产者消费者

RabbitMQ是一个开源的消息队列系统&#xff0c;它实现了高级消息队列协议&#xff08;AMQP&#xff09;&#xff0c; 特点 可靠性&#xff1a;通过持久化、镜像队列等机制保证消息不丢失&#xff0c;确保消息可靠传递。灵活的路由&#xff1a;提供多种路由方式&#xff0c;如…...

Simple-BEV的bilinear_sample 作为view_transformer的解析,核心是3D-2D关联点生成

文件路径models/view_transformers 父类 是class BiLinearSample(nn.Module)基于https://github.com/aharley/simple_bev。 函数解析 函数bev_coord_to_feature_coord的功能 将鸟瞰图3D坐标通过多相机&#xff08;针孔/鱼眼&#xff09;内外参投影到图像特征平面&#xff0…...

Rust嵌入式开发环境搭建指南(基于Stm32+Vscode)

Rust嵌入式开发环境搭建指南(基于Stm32+Vscode) 部分目录如下所示: 目录 简介Rust开发环境安装STM32开发工具链安装VSCode环境配置VSCode插件安装调试器配置项目创建与配置常见问题与解决方案简介 本文档旨在指导开发者如何搭建基于Rust语言的STM32嵌入式开发环境。相比传…...

springboot操作redis集群,注意事项

整合redis可查看博文 springboot 整合redis_springboot整合redis csdn-CSDN博客 集群中操作注意事项 1 多键操作失败&#xff1a; 当使用multiGet等需要同时访问多个键的方法时&#xff0c;如果没有使用Hash Tags&#xff0c;这些键可能会被分配到不同的槽中。如果这些槽位于…...

计算机技术系列博客——目录页(持续更新)

1.1 博客目录专栏 1.1.1 博客文章导航 计算机技术系列博客——目录页 1.1.2 网页资源整理 2.1 计算机科学理论 2.2 软件工程技术 2.2.1.1 编程语言 Java Java语言基础 (1) Java基础知识总结01——Java基础篇 (2) Java基础知识总结02——集合框架篇 (3) Java基础知识总结03—…...

@maptalks/gl-layers中的VectorTileLayer的setStyle属性的全部line配置

maptalks/gl-layers中的VectorTileLayer的setStyle属性的全部line配置 关于 maptalks/gl-layers 中 VectorTileLayer 的 setStyle 方法 在 maptalks/gl-layers 库中&#xff0c;VectorTileLayer 提供了一个灵活的方式来设置矢量瓦片图层的样式。通过调用 setStyle 方法&#xf…...

sql小记,20250319

ps:基于sqlserver 一、绩效管理系统表设计 1.表设计 Users用户表&#xff1a;包含id&#xff0c;用户名&#xff0c;密码。 AppraisalBases评价(职位基数)表&#xff1a;包含职位id&#xff0c;职位年终奖基数 AppraisalCoeffcients评价系数表&#xff1a;包含类别id, 类别&…...

【亚马逊云科技】大模型选型实战(挑选和测评对比最适合业务的大模型)

文章目录 前言1、实验内容2、手册内容 一、环境准备二、Prompt 实战与模型配置2.1 基于 Amazon Bedrock 对比测试不同模型的逻辑推理效果2.2 基于 Amazon Bedrock 对比测试不同模型知识问答能力2.3 Prompt 实战结果分析 三、基于 Amazon Bedrock Evaluations 进行模型评测与自动…...

Linux 用户与组管理实战:经验分享与最佳实践

在 Linux 系统管理中&#xff0c;用户和组的管理是保障系统安全和资源分配的重要环节。本文将深入介绍如何创建和管理用户与组&#xff0c;包括 UID、GID 的设置&#xff0c;主组与附加组的分配&#xff0c;以及常见问题的排查和解决。本文还结合实际操作经验&#xff0c;总结了…...

详解如何通过Python的BeautifulSoup爬虫+NLP标签提取+Dijkstra规划路径和KMeans聚类分析帮助用户规划旅行路线

系统模块&#xff1a; 数据采集模块&#xff08;爬虫&#xff09;&#xff1a;负责从目标网站抓取地点数据&#xff08;如名称、经纬度、描述等&#xff09; 数据预处理模块&#xff08;标签算法&#xff09;&#xff1a;对抓取到的地点数据进行清洗和分类。根据地点特征&…...

Java Stream两种list判断字符串是否存在方案

这里写自定义目录标题 背景初始化方法一、filter过滤方法二、anyMatch匹配 背景 在项目开发中&#xff0c;经常遇到筛选list中是否包含某个子字符串&#xff0c;有多种方式&#xff0c;本篇主要介绍stream流的filter和anyMatch两种方案&#xff0c;记录下来&#xff0c;方便备…...

C语言-指针变量和变量指针

指针 预备知识 内存地址 字节&#xff1a;字节是内存的容量单位&#xff0c;英文名Byte&#xff0c;1Byte8bits 地址&#xff1a;系统为了便于区分每一个字节面对它们的逐一进行编号&#xff08;编号是唯一的&#xff09;&#xff0c;称为内存地址&#xff0c;简称地址。int…...

CMS漏洞-WordPress篇

一.姿势一&#xff1a;后台修改模板拿WebShell 1.使用以下命令开启docker cd /www/wwwroot / vulhub / wordpress / pwnscriptum docker - compose up - d 如果发现不能开启&#xff0c;可以检查版本和端口 2.访问网址登录成功后 外观 &#x1f449;编辑 &#x1f449;404.…...

初识Brainstorm(matlab)

Brainstorm是一款开源应用程序&#xff0c;专门用于分析脑部记录数据&#xff1a;MEG、EEG、fNIRS、ECoG、深部电极等。该应用程序免费&#xff0c;而且不需要Matlab许可证。Brainstorm主要优势是简单直观的图形界面&#xff0c;不需要任何编程知识。具体内容&#xff0c;可查看…...

2025年智能系统、自动化与控制国际学术会议(ISAC 2025)

重要信息 2025 International Conference on Intelligent Systems, Automation and Control 2025年3月28-30日 | 中国西安理工大学 | 会议官网&#xff1a; www.icisac.org 简介 在国家大力推动高质量发展与创新驱动战略的背景下&#xff0c;智能制造与自动化控制行业正迎…...

GGUF、Transformer、AWQ 详解与关系梳理

GGUF、Transformer、AWQ 详解与关系梳理 一、核心概念解析 Transformer 定义 &#xff1a;2017 年 Google 提出的基于自注意力机制的神经网络架构&#xff0c;是大语言模型的通用基础架构。功能 &#xff1a;用于文本生成、翻译、问答等任务&#xff0c;如 BERT、GPT 系列、…...

学习笔记|arduino uno r3|DS1307时钟芯片|Atmega328P| 设置时间|读取时间|无源晶振:DS1307时钟芯片实验

目录 芯片pinout&#xff1a; 实验器件&#xff1a; 实验连线 解决AVR 架构不支持 printf() 方法 使用GetTimeAndDate.ino设置时间&#xff1a; 使用SetTimeAndDate.ino设置时间&#xff1a; 芯片pinout&#xff1a; DS1307 是美国 DALLAS 公司推出的 I 总线接口实时时钟芯…...

Linux--进程创建

进程创建 写时拷贝&#xff08;时间换空间&#xff09; 更新页表项权限为只读----子进程写入----触发系统错误系统缺页中断&#xff0c;系统开始检测&#xff0c;系统判断写入区域是数据区还是代码区&#xff0c;如果是代码区就终结进程&#xff0c;如果是数据区就进行写时拷贝…...

MySQL 创建用户,建库,建表

以下是在 MySQL 中创建用户、数据库、表的详细操作步骤&#xff1a; 一、登录 MySQL -- 使用 root 用户登录&#xff08;需替换为实际密码&#xff09; mysql -u root -p输入密码后回车&#xff0c;进入 MySQL 命令行界面。 二、创建数据库 -- 创建名为 test_db 的数据库&a…...

成都国际数字影像产业园,文创产业运营新典范深度解析​

成都国际数字影像产业园位于成都市蓉北商圈金牛片区福堤路99号&#xff0c;是金牛区政府与树莓集团携手打造的省级“文化科技”融合示范园区。该产业园已成为西南地区乃至全国数字影像产业的一颗璀璨明珠&#xff0c;其成功运营模式堪称文创产业运营的新典范。 产业定位与资源…...

33、如果 std::vector 的元素是指针,需要注意什么?

对 std::vector 元素为指针的情况&#xff0c;需要注意以下几点&#xff1a; 内存管理&#xff1a; 如果 std::vector 存储的是原始指针&#xff0c;那么仅仅清空 vector 或者让 vector 被销毁&#xff0c;并不会释放指针所指向的内存。因此&#xff0c;需要确保在 vector 被销…...

Docker 速通(总结)

Docker 命令 镜像 docker build: 从 Dockerfile 构建镜像。docker pull: 从 Docker Hub 或其他注册表拉取镜像。docker push: 将镜像推送到 Docker Hub 或其他注册表。docker images: 列出本地镜像。docker rmi: 删除本地镜像。 容器 docker run: 创建并启动一个新的容器。…...

算法训练篇06--力扣611.有效三角形的个数

目录 1.题目链接&#xff1a;611.有效三角形的个数 2.题目描述&#xff1a; 3.解法一&#xff1a;(暴力解法)(会超时)&#xff1a; 4.解法二(排序双指针) 1.题目链接&#xff1a;611.有效三角形的个数 2.题目描述&#xff1a; 给定一个包含非负整数的数组 nums &#xf…...

Gin框架学习

一.介绍 Gin是一个用Go语言编写的web框架。它是一个类似于martini但拥有更好性能的API框架, 由于使用了httprouter&#xff0c;速度提高了近40倍。 如果你是性能和高效的追求者, 你会爱上Gin。 下载 go get -u github.com/gin-gonic/gin 二.Gin示例 学习的时候&#xff0c;写在…...

青少年编程与数学 02-011 MySQL数据库应用 07课题、表的操作

青少年编程与数学 02-011 MySQL数据库应用 07课题、表的操作 一、数据库表&#xff08;Table&#xff09;二、创建表语法格式示例注意事项 三、字段的命名规则基本规则命名规范建议示例 四、字段数据类型数值类型字符串类型日期和时间类型其他类型 五、选择合适的数据类型1. **…...

【详细解决】pycharm 终端出现报错:“Failed : 无法将“Failed”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。

昨天在终端一顿操作后突然打开pycharm时就开始报错&#xff1a; 无法将“Failed”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&#xff0c;请确保路径正确&#xff0c;然后再试一次。 所在位置 行:1 字符: 1 Failed to act…...

AcWing 839:模拟堆 ← multiset + unordered_map

【题目来源】 https://www.acwing.com/problem/content/841/ 【题目描述】 维护一个集合&#xff0c;初始时集合为空&#xff0c;支持如下几种操作&#xff1a; 1. I x&#xff0c;插入一个数 x&#xff1b; 2. PM&#xff0c;输出当前集合中的最小值&#xff1b; 3. DM&#…...