共享内存(System V)——进程通信
个人主页:敲上瘾-CSDN博客
进程通信:
- 匿名管道:进程池的制作(linux进程间通信,匿名管道... ...)-CSDN博客
- 命名管道:命名管道——进程间通信-CSDN博客
目录
一、共享内存的原理
二、信道的建立
1.创建共享内存
1.key的作用
2.key的选取
3.shmid的作用
4.key和shmid的区别
5.内存设定的特性
6.shmflg的设定
2.绑定共享内存
3.代码示例
三、利用共享内存通信
1.通信
2.解除绑定
3.销毁共享内存
1.命令行销毁
2.程序中销毁
四、共享内存的生命周期
五、数据安全问题
六、源码
1.comm.hpp
2.server.cc
3.client.cc
一、共享内存的原理
共享内存是通过在物理内存上开辟一块空间,然后让需要通信的进程都映射到这一块空间,这样就使它们看到同一块资源了。
共享内存通信是双向的,也就是说一个进程可以既读又写,使用起来就和C语言的malloc申请到的内存差不多。这种通信方式存在着数据安全问题,会在下文细说。
二、信道的建立
1.创建共享内存
创建共享内存使用shmget函数,它的作用是创建或获取共享内存段的系统调用。
对于shmget的使用来说,虽然操作起来相对简单,但要完全理解其各种参数的设定则较为困难。不过接下来我会进行详细讲解。
shmget声明如下:
#include <sys/ipc.h> #include <sys/shm.h>int shmget(key_t key, size_t size, int shmflg);
- 参数key:用户设定任意一个数,用于区分不同共享内存,通常由ftok生成。
- 参数size:设定共享内存的大小。
- 参数shmflg:标志位,用于指定共享内存段的创建方式和权限。常见的标志包括:
IPC_CREAT:
如果共享内存段不存在,则创建它。IPC_EXCL:
与IPC_CREAT
一起使用,确保创建的共享内存段是新的。- 权限标志:如
0666
,表示所有用户都有读写权限。- 返回值:
- 成功时返回共享内存段的标识符(shmid)。
- 失败时返回
-1
,并设置errno
以指示错误类型。
1.key的作用
- 思考1:在用户层面如何让两个独立进程共享同一块内存?
- 思考2:在匿名管道和命名管道中,用户层面是如何让两个进程确定同一个资源的?
问题2很显然,管道的本质是文件,用户通过让两个程序打开同一个文件名来实现看到同一个资源。
因此,共享内存同样需要一个key来充当类似文件名的功能。
2.key的选取
key参数本质是一个int类型,我们可以直接指定一个数值传入,当然,为了更规范,更专业,我们通常都会使用ftok来生成。
ftok的声明如下:
#include <sys/types.h> #include <sys/ipc.h>key_t ftok(const char *pathname, int proj_id);
- 参数pathnme:一个存在的文件路径(例如
/tmp/myfile
),文件必须存在,否则ftok
会失败。- 参数proj_id:一个整数,用于进一步区分不同的 IPC 对象。
- 返回值:
成功:返回生成的
key_t
键值。失败:返回
-1
,并设置errno
以指示错误原因。
3.shmid的作用
shmid是一个int类型,由shmget返回,在作用上和物理意义上与文件系统中的fd类似。它的作用主要是让用户找到指定的共享内存。而它的物理意义在这里就不提了,感兴趣的话可以等我的下一篇博文(IPC系统)发布。
4.key和shmid的区别
key最终成为系统层区分不同IPC的标志,而shmid则是用户层用来区分不同IPC的标志。
5.内存设定的特性
这里的内存设定指的是shmget函数中的参数size。
当传入的内存不足4096字节(4KB)的倍数时,会扩到4096倍数。但是只会提供size大小的使用空间。这样做可以规避掉一些因为共享内存过多带来的问题。
6.shmflg的设定
对于共享内存,我们可以将程序简单分为创建端和使用端,它们的shmflg设定通常是:
- 创建端:IPC_CREAT | IPC_EXCL | 0666
- 使用端:IPC_CREAT
创建端要保证IPC是最新的,所以需要加IPC_EXCL,然后还需要设定权限。
使用端只需要获取共享内存段的系统调用,因此只用一个IPC_CREAT即可。
2.绑定共享内存
以上我们完成的只是共享内存的创建,接下来还需要把进程绑定到共享内存,使用函数shmat,其中at指的是单词attach。
shmat的声明:
#include <sys/types.h> #include <sys/shm.h>void *shmat(int shmid, const void *shmaddr, int shmflg);
- 参数shmid:传入从shmget中返回的shmid来指定共享内存。
- 参数shmaddr:指定共享内存段附加到进程地址空间的位置,通常设为nullptr,系统会自动选择一个合适的地址。
- 参数shmflg:读写方式,常用的有:
SHM_RDONLY
:以只读方式附加共享内存段。0
:以读写方式附加共享内存段。- 返回值:
- 成功时,返回共享内存段附加到进程地址空间的起始地址。
- 失败时,返回
(void *) -1
,并设置errno
。
3.代码示例
创建端程序:
int main()
{//生成一个keyint key = ftok(".", 48);//创建共享内存int shmid = shmget(key, 4069, IPC_CREAT | IPC_EXCL | 0666);//连接到共享内存void* p = shmat(shmid,nullptr,0);//使用共享内存//... ...return 0;
}
使用端程序:
int main()
{//生成一个相同keyint key = ftok(".", 48);//获取到共享内存的系统调用int shmid = shmget(key, 4069, IPC_CREAT);//连接到共享内存void* p = shmat(shmid,nullptr,0);//使用共享内存//... ...return 0;
}
注意:为了简洁和方便说明问题,以上代码省略了头文件的包含和返回值有效性的判断等等,在实际开发中可不敢省略。
三、利用共享内存通信
1.通信
上文我们只是完成了信道的建立,接下来我们进行通信,通过上面的操作,我们已经获取到共享内存的起始地址。
它的用法与C语言的malloc申请的内存用法相同,只是共享内存可以同时被两个进程访问。
如下写端:
int main()
{int key = ftok(".", 48);int shmid = shmget(key, 4069, IPC_CREAT | IPC_EXCL | 0666);void* p = shmat(shmid,nullptr,0);//使用共享内存char* chp = (char*)p;for(int i='a';i<='z';i++){sleep(1);*chp=i;chp++;}return 0;
}
读端:
int main()
{int key = ftok(".", 48);int shmid = shmget(key, 4069, IPC_CREAT);void* p = shmat(shmid,nullptr,0);//使用共享内存char* chp = (char*)p;while(true){sleep(1);cout<<chp<<endl;}return 0;
}
注意:为了获取到同一个共享内存,我们设定的key必须一致。
2.解除绑定
如果进程退出时没有解除绑定,共享内存段仍然会保留在系统的共享内存资源中,直到显式删除(通过 shmctl
或系统重启)。
使用shmdt来解除绑定,其中dt代表单词delete。
shmdt的声明:
int shmdt(const void *shmaddr);
参数shmaddr:需要断开连接的共享内存的起始地址。
返回值:
- 成功:返回0。
- 失败:返回-1,并设置errno以指示错误原因。
一个共享内存,与它绑定的程序的个数是由一个引用计数机制进行维护的,当shmdt成功,引用计数减1。
3.销毁共享内存
共享内存不会随程序的结束而销毁,它是随内核的,因此需要显式地进行销毁,可以使用shmctl函数。或在命令行中使用指令进行销毁。
1.命令行销毁
1.1.查看共享内存信息
ipcs -m
如下:
这里解释一下nattch信息:它表示与该共享内存连接的程序个数。
1.2.销毁共享内存
ipcrm -m 2
这里需要填入shmid(即这里的2)来指定共享内存。
2.程序中销毁
在程序中销毁我们使用函数shmctl,其中ctl代表单词control。
shmctl声明如下:
#include <sys/ipc.h> #include <sys/shm.h>int shmctl(int shmid, int cmd, struct shmid_ds *buf);
- 参数shmid:传入从shmget返回的shmid来指定需要销毁的共享内存。
- 参数cmd:需要传入一个操作选项,操作选项很多,而IPC_RMID就是用来销毁共享内存的。
- 参数shmid_ds:这是一个输出型参数,如果你需要获取共享内存的信息,则传入一个shmid_ds类型的指针来接收,如果不是通常传入nullptr即可。
- 返回值:
- 成功时返回
0
。- 失败时返回
-1
,并设置errno
以指示错误类型。
注:命令行销毁和程序中销毁效果是一样的,因为命令行销毁底层还是调用了shmctl函数。
四、共享内存的生命周期
共享内存的生命周期是不随进程的,而是随内核,如果没有显示删除它就会一直存在,尽管相关的进程已经退出。直到重装系统才得以释放。
使用shmctl释放共享内存存在的情况
1.正常释放
当nattach(引用计数)为0时,即没有进程与它绑定,被正常释放。
2.共享内存段被标记为已删除,但仍有进程附加(shmat)
共享内存段已经被标记为已删除(不能附加到新的进程),但之前仍有一些进程附加到该共享内存段并正在使用。所以共享内存段不会被立即释放。只有当所有附加的进程都调用 shmdt
分离后,系统才会释放资源。
五、数据安全问题
共享内存最大的优点就是快,相比使用管道技术,它减少了中间复杂转化和拷贝工作,而是直接对物理内存进行访问。
但它也有一个致命的缺点,相比管道技术,共享内存它的读端和写端是不带有同步机制的,这就很容易使得数据混乱,也就是造成数据不一致问题。
比如我们写端写入“hello world”,而读端读到的可能是“he”,“ll”,“o wor”,“ld”等等无法预测的奇葩数据。 读端一个劲地读,不会管写端这句话是否已经说完,而且也无法知道。
当我们不了解锁的情况下想要解决这个问题,可以利用命名管道来解决,因为命名管道带有同步机制,我们用它的write和read函数来保护数据的安全,当然write和read并不用写或读什么有意义的数据。
非常感谢您能耐心读完这篇文章。倘若您从中有所收获,还望多多支持呀!
六、源码
1.comm.hpp
#pragma
#include <iostream>
#include <string>
#include <cstdio>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
#define SIZE 1024
#define KEY_NUM 0x66
#define PATH "."
#define CREATE "create"
#define USE "user"
#define ERROR(str) \{ \perror(str); \exit(1); \}using namespace std;
class Shm
{
private:void Create(int flg){_shmid = shmget(_key, _size, flg);if (_shmid < 0){ERROR("shmget");}printf("shmget success id:%d\n", _shmid);}void Attach(){_start_mem = shmat(_shmid, nullptr, 0);if ((long long)_start_mem < 0){ERROR("shmat");}}void Destroy(){int m = shmdt(_start_mem);if (m < 0){ERROR("shmdt");}int n = shmctl(_shmid, IPC_RMID, nullptr);if (n < 0){ERROR("shmctl");}}public:Shm(string path, int projid, string user): _shmid(-1), _size(SIZE), _usertype(user){_key = ftok(path.c_str(), projid);if (_key < 0){ERROR("ftok");}printf("ftok success id:%d\n", _key);if (_usertype == CREATE)Create(IPC_CREAT | IPC_EXCL | 0666);elseCreate(IPC_CREAT);Attach();}void *VirtualAddr(){return _start_mem;}~Shm(){Destroy();}private:int _shmid;int _size;int _key;string _usertype;void *_start_mem;
};
2.server.cc
#include"comm.hpp"
int main()
{Shm sm(PATH,KEY_NUM,CREATE);char* ps = (char*)sm.VirtualAddr();while(true){sleep(1);printf("%s\n",ps);}return 0;
}
3.client.cc
#include"comm.hpp"
int main()
{Shm sm(PATH,KEY_NUM,USE);char* ps = (char*)sm.VirtualAddr();for(char ch='0';ch<'z';ch++){sleep(1);*ps = ch;ps++;*ps='\0';}return 0;
}
相关文章:
共享内存(System V)——进程通信
个人主页:敲上瘾-CSDN博客 进程通信: 匿名管道:进程池的制作(linux进程间通信,匿名管道... ...)-CSDN博客命名管道:命名管道——进程间通信-CSDN博客 目录 一、共享内存的原理 二、信道的建立 …...
考研数学非数竞赛复习之Stolz定理求解数列极限
在非数类大学生数学竞赛中,Stolz定理作为一种强大的工具,经常被用来解决和式数列极限的问题,也被誉为离散版的’洛必达’方法,它提供了一种简洁而有效的方法,使得原本复杂繁琐的极限计算过程变得直观明了。本文&#x…...
12 DHCP的内容和HTTP的改良
一、回顾 计算机分配相关身份 网络号、主机号 网络号内的主机识别 局部网通信网关 不同网络的通信DNS服务器 域名解析 因特网通信 二、DHCP协议 建议学习前看这个视频,14分钟,所有的知识点都有,很容易理解 1、理解 DHCP 的全称是 Dynam…...
多光谱相机数据采集过程中常见仪器
1.BF1515多光谱相机 2.VIX-N220推扫式可见光近红外高光谱相机 覆盖光谱范围:400-1000nm; 光谱分辨率:2nm; 设备配套软件:VIX-N220、XuanDo(用于调节相机推扫速度); 镜头调节所需材料:黑色条…...
【调研】olmOCR解析PDF
测试用例: olmOCR GOT-OCR 将最底下没有文字的部分,可能是样式解析出重复 olmOCR GOT-OCR 无重复 重复 速度上,olmOCR效果更快 效果上,olmOCR解析得到的内容排版更加清晰整齐,而且对于6份GOT-OCR有重复的测…...
蓝桥杯随笔练——二分模板
答案 #include <bits/stdc.h> //洛谷2249 using namespace std;const int N 1e610; int n,m; int a[N];int Array_Search(int a[],int len,int x) {int L 0,R len1;while(L1 < R){int mid (RL) >> 1;if(a[mid] < x ) L mid;else R mid;}if(a[R] x) r…...
【Golang】第三弹----运算符
笔上得来终觉浅,绝知此事要躬行 🔥 个人主页:星云爱编程 🔥 所属专栏:Golang 🌷追光的人,终会万丈光芒 🎉欢迎大家点赞👍评论📝收藏⭐文章 一、运算符介绍 运算符是一…...
MongoDB 聚合管道速成教程
一、引言 MongoDB 的聚合管道(Aggregation Pipeline)是一种强大的数据处理工具,它允许你对文档进行一系列的操作,如过滤、转换、分组和聚合等。聚合管道由多个管道组成,每个管道对输入的文档进行特定的处理࿰…...
「JavaScript深入」二进制数据处理详解「Blob、File、FileReader、ArrayBuffer、Typed Arrays、DataView」
二进制数据处理详解 1. Blob(Binary Large Object)Blob 的特性创建 BlobBlob 主要方法Blob 的应用 2. FileFile 对象的属性获取 File 对象 3. FileReader创建 FileReader主要方法主要事件文件上传与读取内容示例文件分块读取示例 4. ArrayBuffer 与 Type…...
信号处理之插值、抽取与多项滤波
信号处理之插值、抽取与多项滤波 一、问题背景 插值(Interpolation)与抽取(Decimation)是数字信号处理中采样率转换的核心操作: 插值:在信号中插入新样本以提高采样率( L L L倍)抽取:按比例 M M M降低采样率…...
关于WPS的Excel点击单元格打开别的文档的两种方法的探究
问题需求 目录和文件结构如下: E:\Dir_Level1 │ Level1.txt │ └─Dir_Level2│ Level2.txt│ master.xlsx│└─Dir_Level3Level3.txt现在要在master.xlsx点击单元格进而访问Level1.txt、Level2.txt、Level3.txt这些文件。 方法一:“单元格右键…...
蓝桥 2109统计子矩阵
问题描述 给定一个NM 的矩阵 A, 请你统计有多少个子矩阵 (最小 11, 最大 NM) 满足子矩阵中所有数的和不超过给定的整数 K ? 输入格式 第一行包含三个整数 N,M 和 K. 之后 NN 行每行包含 M 个整数, 代表矩阵 A. 输出格式 一个整数代表答案。 样例输入 3 4 10 1 2 3 4 5…...
AF3 make_fixed_size函数解读
AlphaFold3 data_transforms 模块的 make_fixed_size 函数的作用是将输入的蛋白质特征字典 protein 中的各个特征张量调整为固定大小。这是为了确保在批量处理时,所有特征张量的形状一致,从而避免形状不匹配的问题。 源代码: import itertools import torch from src.con…...
前端模块管理新思路:如何使用 Import Maps
前言 前端开发中,我们常常需要使用各种库和模块来构建功能丰富的应用。在传统方式中,管理这些库和模块的引用可能会有些繁琐。 幸运的是,Import Maps 的出现为我们提供了一种更简洁和高效的解决方案。今天我们就来聊聊如何使用 Import Maps。…...
交换机、路由器、网关、MAC地址——从入门到实战
你是否好奇,当你在手机上点击一个网页链接时,数据是如何从你的设备“飞”到千里之外的服务器并返回的?背后离不开交换机、路由器、网关和MAC地址的默契配合。本文用通俗语言实战场景,带你彻底搞懂这些网络核心组件,从此…...
【江协科技STM32】ADC数模转换器-学习笔记
ADC简介 ADC(Analog-Digital Converter)模拟-数字转换器ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁,ADC是一种将连续的模拟信号转换为离散的数字信号的设备或模块12位逐次逼近型…...
LanceDB快速入门之基本操作与API一览
LanceDB可以以多种方式运行 可以嵌入到现有后端(如您的 Django、Flask、Node.js 或 FastAPI 应用程序)中直接从如 Jupyter 笔记本等客户端应用程序中用于分析工作负载部署为远程无服务器数据库 安装 Python: pip install lancedbTypeScrip…...
Spring Boot 整合 Redis
以下是 Spring Boot 整合 Redis 的指南,涵盖配置、基本操作、高级用法及常见问题解决。 1. 添加依赖 在 pom.xml 中添加 Spring Data Redis 和连接池依赖: <dependency><groupId>org.springframework.boot</groupId><artifactId&…...
七层协议攻防实战:从HTTP慢速攻击到DNS隧道检测
一、七层协议攻击类型与特征 攻击类型协议特征HTTP慢速攻击HTTP低速率发送不完整请求DNS隧道DNS异常长域名、高频率TXT查询API滥用攻击HTTP高频调用关键接口(如短信发送)WebSocket洪水WebSocket海量小消息耗尽服务器资源 二、HTTP协议深度防护 1. 慢速…...
Java CAS(Compare-And-Swap)概念及原理
Java CAS(Compare-And-Swap)概念及原理 1. CAS的基本概念 CAS(Compare-And-Swap)是一种无锁编程的核心技术,用于实现多线程环境下的原子操作。其核心思想是: “先比较,再交换”。具体操作包含…...
内存检测工具——Qt Creator
前言 检测内存错误的工具,有很多个,我今天粗浅的学了一下可在Qt上使用的工具们: Dr.Memory 工具之前我曾在关注的博主上看到相关的博客:C(Qt)软件调试---内存调试器Dr.Memory(21)_dr. memory-CSDN博客 今…...
Ubuntu切换lowlatency内核
文章目录 一. 前言二. 开发环境三. 具体操作 一. 前言 低延迟内核(Lowlatency Kernel) 旨在为需要低延迟响应的应用程序设计的内核版本。Linux-lowlatency特别适合音频处理、实时计算、游戏和其他需要及时响应的实时任务。其主要特点是优化了中断处理、调…...
侯捷 C++ 课程学习笔记:STL标准库与泛型编程
STL 体系结构基础介绍 STL 六大部件: 容器(Containers) 分配器(Allocators) …...
Java 大视界 -- Java 大数据在智能安防视频摘要与检索技术中的应用(128)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
19874并查集
19874并查集 ⭐️难度:中等 🌟考点:并查集、数据结构 📖 📚 import java.util.*;public class Main {static int N 100010;static int[] a new int[N];static int[] p new int[N];static int n;static int m;st…...
ABC 376
目录 D. Cycle D. Cycle(改) E. Max Sum D. Cycle 这道题就是个 01 最短路,直接从 1 开始 bfs 看能不能回到 1 #include<bits/stdc.h> #define int long long using namespace std; const int N 2e5 5, INF 1e18;struct node {int …...
win32汇编环境,对 WM_MOUSEMOVE 消息的理解
;运行效果 ;win32汇编环境,对 WM_MOUSEMOVE 消息的理解 ;理解在 WM_MOUSEMOVE 消息发生时,同时来的wParam和lParam值的含义,并取出各自的值进行运用。从这例子也可以更好的理解windows的消息机制. ;WM_MOUSEMOVE消息就是当鼠标移动时,发送给窗…...
第27周JavaSpringboot电商进阶开发 2.常用功能进阶
电商常用功能进阶 - 课程笔记整理 Excel解析与处理 一、课程内容概述 本小节开始进入电商常用功能进阶部分,主要讲解以下内容: Excel的解析和处理商品图片的处理Valid注解对列表的验证订单数变化趋势图Spring Boot高级功能 二、Excel解析与处理的背…...
网络安全基础知识:从零开始了解网络安全
### 网络安全基础知识:从零开始了解网络安全 欢迎来到《零基础入门到独立参加网络安全比赛》系列教程的第一篇!在这篇文章中,我们将从最基础的概念开始,深入探讨网络安全的定义、重要性、常见的网络攻击类型,以及网络…...
【A2DP】蓝牙A2DP协议剖析:从架构到规范
目录 一、A2DP 协议架构 1.1 A2DP 协议栈结构组成 1.2 协议栈各部分的关系与作用 二、设备配置与角色定义(Configurations and roles ) 2.1 角色定义 2.2 配置示例与角色体现 三、用户需求与场景 3.1 用户需求与场景 3.2 协议限制 3.3 协议要求…...
python力扣15. 三数之和
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意:答案中不可以包含重复的三元组。 示例 1&am…...
Linux之系统文件目录理解
1.boot/ 存储启动系统的相关文件的 2.swap/ 虚拟内存 3.dev/ 用于存放设备文件(device files)。这些文件是操作系统与硬件设备之间的接口,允许用户和程序通过文件操作的方式访问硬件资源 字符设备(Character Devices…...
uvm_transaction, uvm_seq_item, uvm_object, uvm_component的关系
uvm_object ├── uvm_component (验证环境中的静态组件) └── uvm_transaction└── uvm_sequence_item (用于sequence-driver交互的事务) 2. 核心类的作用与区别 (1) uvm_object 定位:所有UVM类的基类。 功能: 提供基础的对象操作&…...
Reflect.get和target[key]有何不同?
主要区别在this指向不同,下面输出张三还是李四?: const person{name:张三,get FullName(){return this.name;},};let personProxynew Proxy(person,{get(target,key){return Reflect.get(target,key)//或者return target[key]}});const p1{__proto__:pe…...
K8s 1.27.1 实战系列(十)PV PVC
一、核心概念与关系 1、PV(Persistent Volume) PV 是集群中的持久化存储资源,由管理员预先创建并配置,独立于 Pod 生命周期。它抽象了底层存储(如 NFS、云存储等),定义存储容量、访问模式(如 ReadWriteOnce)、回收策略(Retain/Delete/Recycle)等属性。例如,一…...
JQuery
1.jquery介绍 jQuery是目前使用最广泛的javascript函数库。据统计,全世界排名前100万的网站,有46%使用jQuery,远远超过其他库。微软公司甚至把jQuery作为他们的官方库。 jQuery的版本分为1.x系列和2.x、3.x系列,1.x系列兼容低版…...
「AI 加持的高效架构」高并发场景下的服务器成本优化
网罗开发 (小红书、快手、视频号同名) 大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等…...
html css 笔记
01_浏览器相关知识 五大主流浏览器: Chrome Safari IE Firefox Opera (拥有自己的内核) 四大内核: webkit Trident Gecko blink. 02_网页相关知识 构成 网址 网站 网页 网页标准: 结构 表现 行为 分别对应 HTML CSS JavaScript 03_HTML简介 H…...
通义万相 2.1:AIGC 领域的 “王炸” 组合如何颠覆创作生态?
引言 在数字化和人工智能的飞速发展中,AIGC(AI生成内容)技术已经成为推动创作、设计和内容生成领域创新的核心力量。而当通义万相2.1与蓝耘智算平台强强联手,这一“王炸”组合不仅提升了AIGC的效率,还为创作生态带来了…...
Math.NET Numerics 库怎么装
你提到的缺少的库是 Math.NET Numerics。 关于 Math.NET Numerics Math.NET Numerics 是一个用于 .NET 平台的开源数学库,提供了以下功能: 线性代数(矩阵运算、求解线性方程组等)。数值计算(积分、微分、优化等&…...
NPM安装与配置全流程详解(2025最新版)
写目录 一、环境准备与Node.js安装1. 下载Node.js(含NPM)2. 验证安装 二、NPM核心配置优化1. 全局模块与缓存路径设置2. 镜像加速3. 代理配置(企业网络适用) 三、NPM基础操作指南1. 项目初始化2. 包管理命令3. 依赖锁定与版本管理…...
python-52-基于Langchain和Faiss实现向量存储和检索的技术原理
文章目录 1 文本加载与预处理1.1 计算文本的MD5哈希值1.2 加载文本并计算哈希2 初始化向量存储2.1 基于Ollama的嵌入模型2.2 获取code和id的对应关系2.3 清空索引向量2.4 基于HuggingFaceEmbeddings的嵌入模型2.4.1 将模型下载到本地2.4.2 使用方式3 添加新文本3.1 处理新文本并…...
游戏引擎学习第140天
回顾并为今天的内容做准备 目前代码的进展到了声音混音的部分。昨天我详细解释了声音的处理方式,声音在技术上是一个非常特别的存在,但在游戏中进行声音混音的需求其实相对简单明了,所以今天的任务应该不会太具挑战性。 今天我们会编写一个…...
Jetpack Navigation 实战:Fragment 和 Activity 的交互与导航
在 Android 开发中,使用 Jetpack Navigation 组件可以方便地管理 Fragment 和 Activity 之间的导航。以下是如何使用 Jetpack Navigation 实现 Fragment 之间、Activity 之间以及 Activity 与 Fragment 之间跳转的实战示例。 1. 添加依赖 首先,在 build.…...
Linux中的基本指令(上)
目录 ls指令 判断linux中文件 pwd指令 认识路径 编辑 绝对路径/相对路径 cd指令 简要理解用户 理解家目录 echo指令和printf指令 touch指令 mkdir指令 cat指令 tree指令 rmdir指令和rm指令 man指令 cp指令 which指令 alias 指令 date指令 cal指令 理解…...
多用户网页在线聊天室(测试报告)
文章目录 多用户网页在线聊天室一,项目概括1.1 项目名称1.2 测试时间1.3 项目背景1.3 编写目的 二,测试计划2.1 测试环境与配置2.2 测试用例2.3实际执行用例2.3.1登录2.3.2聊天消息列表展示2.3.3聊天消息详情页展示2.3.4联系人页展示2.3.5信息的编辑与发…...
字节青训营后端方向的个人总结(2025年3月4日)
字节青训营的结营总结(25寒假) ——致青训营队友的一封信 明天就是大项目结项的日子了,不知道大家在这方面学习、精进了多少,也许有的朋友收获颇多并且已经完成了项目,我个人对此表示由衷的恭喜和祝贺。 当初自告奋…...
VX iOS分析随记
断SVC的时候看调用栈,发现里面一个特别大的ollvm函数。vx版本8054 * thread #36, queue com.apple.root.default-qos, stop reason breakpoint 4.1 frame #0: 0x0000000111ad6124 WeChat___lldb_unnamed_symbol1315083 20 WeChat___lldb_unnamed_symbol13150…...
docker 小记
一、卸载 查看当前版本 docker -v2. 如果有,先停止docker systemctl stop docker如果是yum安装,卸载方式为 #已防版本冲突,直接卸载 yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-lat…...
AI代码编程辅助工具
现在AI火的一塌糊涂,作为技术应该更应该关注当前AI对编程行业的影响。 分享下当前网络上最火的网络编程辅助工具。 以下是个人搜集到的可以对编程起辅助作用的工具: 2025年最佳AI编程辅助工具 1. GitHub Copilot 这个工具也许你已经在使用了࿰…...