Linux 内核学习 3b - 和copilot 讨论pci设备的物理地址在内核空间和用户空间映射到虚拟地址的区别
前提知识: 可以把内核当作一个需要特殊权限运行的程序,那么不同的程序,相同的设备物理地址就会映射到不同的虚拟地址 (见Linux 内核学习 3 - 虚拟内存和物理内存)。
You said
同一个pcie 设备物理地址在linux 内核和用户程序里面对应的虚拟地址是一样的吗
Copilot said
在Linux系统中,同一个PCIe设备在内核和用户程序中的虚拟地址通常是不同的。
在内核空间,内核使用自己的地址空间进行内存管理,而用户空间的程序使用的是不同的地址空间。即使设备在物理上是同一个,内核和用户程序对其访问使用的虚拟地址也会不同。内核通过内存映射(memory mapping)将设备的物理地址映射到内核的虚拟地址空间中,而用户程序通过系统调用(如 mmap)将设备的物理地址映射到自己的虚拟地址空间中。
这种地址分离的机制是为了保护内存安全,防止用户程序直接访问内核空间,确保系统的稳定性和安全性。需要注意的是,这样的设计也意味着在内核编程和用户态编程中对设备地址的处理会有所不同。
如果你对某个具体场景有疑问或需要进一步的说明,请告诉我!
You said
内核程序和用户程序分别如何把pci 设备的物理地址转到虚拟地址
Copilot said
在Linux系统中,内核程序和用户程序将PCI设备的物理地址转换为虚拟地址的方法有所不同。
内核程序
在内核空间,内核程序使用内存映射机制将PCI设备的物理地址映射到内核虚拟地址空间。这通常通过以下步骤完成:
- PCIe设备枚举:内核通过PCI子系统枚举所有连接的PCIe设备,并读取其配置空间,获取设备的物理地址。
- 内核内存映射:使用 ioremap 函数将设备的物理地址映射到内核的虚拟地址空间。ioremap 函数的语法如下:
void __iomem *ioremap(resource_size_t phys_addr, unsigned long size);
phys_addr 是设备的物理地址,size 是映射的内存大小。
用户程序
在用户空间,用户程序需要通过系统调用将PCI设备的物理地址映射到其虚拟地址空间。通常使用 mmap 系统调用来实现:
- 打开设备文件:用户程序首先需要打开与PCI设备对应的设备文件,通常位于 /dev 目录下。例如:
int fd = open("/dev/my_pci_device", O_RDWR | O_SYNC);
- 内存映射:使用 mmap 函数将设备的物理地址映射到用户进程的虚拟地址空间。mmap 函数的语法如下:
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
fd 是设备文件描述符,offset 是从设备的物理地址开始的偏移量,length 是映射的内存大小。
示例代码
以下是一个用户程序使用 mmap 进行内存映射的简单示例:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
int main() {
int fd;
void *map_base;
off_t target = 0xXXXXXXXX; // PCI设备的物理地址
size_t length = 4096; // 映射的内存大小
// 打开设备文件
fd = open("/dev/my_pci_device", O_RDWR | O_SYNC);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
// 内存映射
map_base = mmap(0, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target);
if (map_base == MAP_FAILED) {
perror("mmap");
close(fd);
exit(EXIT_FAILURE);
}
printf("Memory mapped at address %p\n", map_base);
// 访问映射的内存
// *(volatile unsigned int *)(map_base + offset) = value;
// 取消映射和关闭文件
munmap(map_base, length);
close(fd);
return 0;
}
希望这些信息和示例代码对你有所帮助!如果你有更多问题或需要进一步的说明,请告诉我!
You said
mmap() 调用内核里面的什么函数?是不是也是ioremap()
Copilot said
在Linux中,用户空间的 mmap() 系统调用并不是直接调用内核的 ioremap() 函数。它们虽然在功能上都有将物理地址映射到虚拟地址空间的作用,但其机制和层次有所不同。
mmap() 的调用流程
当用户程序调用 mmap() 时,内核会进行一系列的处理步骤来完成内存映射。具体来说, mmap() 调用的流程如下:
- 系统调用入口:用户程序调用 mmap() 系统调用,控制权转移到内核。
- 内核处理:内核根据映射的参数(如文件描述符、偏移量等),通过文件操作结构 file_operations 的 mmap 成员函数来处理请求。如果映射的是设备文件,则设备驱动程序需要实现这个 mmap 函数。
- 驱动程序处理:设备驱动程序实现的 mmap 函数会调用特定的内核函数来进行物理地址到虚拟地址的映射。
ioremap() 的作用
ioremap() 是一个内核函数,主要用于将I/O设备的物理地址映射到内核虚拟地址空间中,通常在内核模块或驱动程序中使用,而不是直接在用户空间中调用。
总结
虽然 mmap() 和 ioremap() 都涉及到内存映射,但它们作用于不同的层次和场景。mmap() 是用户空间和内核空间之间的接口,而 ioremap() 是内核内部的内存映射工具。
希望这能帮助你更好地理解这两个函数的区别!如果你还有其他问题,随时告诉我。
You said
file_operations 的 mmap 成员函数一般怎么实现
Copilot said
在Linux内核中,实现 file_operations 结构体的 mmap 成员函数需要根据设备的具体特性来映射内存。这通常涉及到将设备的物理内存映射到用户空间,使得用户程序可以直接访问设备的内存。
以下是一个简化的示例,展示了如何在设备驱动程序中实现 mmap 成员函数:
1. 定义 file_operations 结构体
static const struct file_operations my_device_fops = {
.owner = THIS_MODULE,
.open = my_device_open,
.release = my_device_release,
.mmap = my_device_mmap, // mmap 成员函数
// 其他成员函数...
};
2. 实现 mmap 成员函数
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/io.h>
static int my_device_mmap(struct file *filp, struct vm_area_struct *vma)
{
unsigned long phys_addr;
unsigned long vma_size = vma->vm_end - vma->vm_start;
unsigned long pfn;
// 获取设备的物理地址(根据具体设备情况获取)
phys_addr = get_device_phys_addr();
// 检查映射大小是否合适
if (vma_size > DEVICE_SIZE) {
return -EINVAL;
}
// 将物理地址转换为页帧号(Page Frame Number, PFN)
pfn = phys_addr >> PAGE_SHIFT;
// 将物理内存映射到用户空间
if (remap_pfn_range(vma, vma->vm_start, pfn, vma_size, vma->vm_page_prot)) {
return -EAGAIN;
}
return 0;
}
3. 获取设备的物理地址
get_device_phys_addr() 函数是一个假设函数,实际实现中你需要根据具体设备获取其物理地址。例如,对于PCI设备,可以使用 pci_resource_start() 函数获取。
4. 注册设备
在驱动程序的初始化函数中注册设备,并将 file_operations 结构体关联到设备上:
static int __init my_device_init(void)
{
int result;
// 注册字符设备
result = register_chrdev(MY_DEVICE_MAJOR, "my_device", &my_device_fops);
if (result < 0) {
printk(KERN_WARNING "Can't register device\n");
return result;
}
return 0;
}
static void __exit my_device_exit(void)
{
// 注销字符设备
unregister_chrdev(MY_DEVICE_MAJOR, "my_device");
}
module_init(my_device_init);
module_exit(my_device_exit);
MODULE_LICENSE("GPL");
解释
- file_operations 结构体:定义了驱动程序对各种文件操作的实现,包括 mmap。
- mmap 成员函数:负责将设备的物理内存映射到用户空间。这是通过 remap_pfn_range() 函数实现的,它将物理页帧号(PFN)映射到用户虚拟地址。
- 物理地址获取:具体的物理地址获取方式依赖于设备类型。对于PCI设备,常用 pci_resource_start() 等函数。
希望这个示例能够帮助你理解如何实现 file_operations 结构体的 mmap 成员函数。如果你有更具体的问题或需要进一步的解释,随时告诉我!
You said
ioremap() 底层原理
Copilot said
ioremap() 是Linux内核中的一个关键函数,用于将I/O设备的物理地址空间映射到内核的虚拟地址空间。它主要用于内核模块或驱动程序中,以便访问设备的寄存器和内存。下面是 ioremap() 的底层原理和实现机制:
1. 地址空间转换
ioremap() 函数的核心任务是将设备的物理地址转换为内核的虚拟地址,这样内核就可以使用普通的指针来访问设备的寄存器和内存。这个转换通过页表(Page Table)实现,页表是操作系统内存管理单元(MMU)的关键组件。
2. 内存映射
ioremap() 会将指定的物理地址范围映射到内核的虚拟地址空间中,并且标记这些内存区域为非缓存(uncached)或强制同步(write-through),以确保对I/O设备的访问是直接且一致的。
3. 实现细节
ioremap() 的实现涉及多个内核函数和数据结构,以下是一个简化的示例:
源码片段(简化版)
void __iomem *ioremap(resource_size_t phys_addr, unsigned long size)
{
// 检查参数和地址范围
if (!phys_addr || !size || phys_addr + size < phys_addr) {
return NULL;
}
// 创建和初始化虚拟内存区域(vma)
struct vm_struct *area;
area = get_vm_area(size, VM_IOREMAP);
if (!area) {
return NULL;
}
// 设置物理地址到虚拟地址的映射
if (ioremap_page_range(area->addr, area->addr + size, phys_addr, PAGE_KERNEL_IO)) {
vunmap(area->addr);
return NULL;
}
return (void __iomem *)area->addr;
}
- 参数检查:首先检查传入的物理地址和大小是否合法。
- 创建虚拟内存区域:使用 get_vm_area() 函数为映射创建一个新的虚拟内存区域。
- 设置页表映射:使用 ioremap_page_range() 函数设置物理地址到虚拟地址的映射,并将其标记为 I/O 区域。
4. 页表设置
ioremap_page_range() 是设置页表映射的关键函数,它将物理地址映射到内核虚拟地址,并设置页表条目(PTE)为非缓存和 I/O 区域:
int ioremap_page_range(unsigned long addr, unsigned long end, phys_addr_t phys_addr, pgprot_t prot)
{
// 设置页表条目
return map_vm_area(addr, end, phys_addr, prot);
}
总结
ioremap() 函数通过创建虚拟内存区域并设置页表映射,将I/O设备的物理地址映射到内核的虚拟地址空间中,使得内核可以方便地访问设备的寄存器和内存。这个过程涉及到参数检查、虚拟内存区域创建、页表设置等步骤。
希望这些信息对你理解 ioremap() 的底层原理有所帮助!如果你有更多问题或需要进一步的解释,随时告诉我!
You said
ioremap_page_range() 和remap_pfn_range()有什么不同?既然都是物理地址转换虚拟地址,是不是可以互相替代
Copilot said
ioremap_page_range() 和 remap_pfn_range() 都是用于在内核中进行内存映射的函数,但它们的用途和使用场景有所不同。
ioremap_page_range()
- 用途:主要用于内核开发中,将物理地址范围映射到内核虚拟地址空间。
- 使用场景:通常用于将设备的物理内存映射到内核空间,以便内核能够直接访问设备的寄存器和内存。它通常在 ioremap() 函数内部调用。
- 调用位置:一般在内核模块或驱动程序中使用,用于设置页表条目,将物理地址映射到内核虚拟地址。
- 示例代码:
int ioremap_page_range(unsigned long addr, unsigned long end, phys_addr_t phys_addr, pgprot_t prot) {
// 设置页表条目
return map_vm_area(addr, end, phys_addr, prot);
}
remap_pfn_range()
- 用途:用于将物理页帧号(PFN)映射到用户空间的虚拟地址。
- 使用场景:主要在实现设备驱动程序的 mmap 操作时使用,将设备的物理内存映射到用户空间,使得用户进程能够直接访问设备内存。
- 调用位置:通常在设备驱动程序中实现 file_operations 的 mmap 成员函数时调用。
- 示例代码:
int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn, unsigned long size, pgprot_t prot) {
// 将物理页帧号映射到用户空间
return io_remap_pfn_range(vma, addr, pfn, size, prot);
}
关键区别
- 调用层次:ioremap_page_range() 主要在内核空间中使用,而 remap_pfn_range() 则用于从内核空间映射到用户空间。
- 使用场景:ioremap_page_range() 常用于内核内部的设备内存映射,而 remap_pfn_range() 用于用户空间的设备内存映射。
- 功能细节:remap_pfn_range() 更侧重于将物理页帧号(PFN)映射到用户空间的虚拟地址,而 ioremap_page_range() 则用于内核空间的地址映射。
总结来说,虽然它们都涉及物理地址到虚拟地址的转换,但由于应用场景和调用层次的不同,它们并不能直接互相替代。如果你有具体的使用场景或问题需要解决,可以告诉我,我可以提供更针对性的建议!
总结: 可能用户空间的应用程序和内核程序对于MMU过程不一样,导致需要调用不同的函数去做这个映射。
相关文章:
Linux 内核学习 3b - 和copilot 讨论pci设备的物理地址在内核空间和用户空间映射到虚拟地址的区别
前提知识: 可以把内核当作一个需要特殊权限运行的程序,那么不同的程序,相同的设备物理地址就会映射到不同的虚拟地址 (见Linux 内核学习 3 - 虚拟内存和物理内存)。 You said 同一个pcie 设备物理地址在linux 内核和用…...
算法【有依赖的背包】
有依赖的背包是指多个物品变成一个复合物品(互斥),每件复合物品不要和怎么要多种可能性展开。时间复杂度O(物品个数 * 背包容量),额外空间复杂度O(背包容量)。 下面通过题目加深理解。 题目一 测试链接:[NOIP2006 提…...
【Linux】 冯诺依曼体系与计算机系统架构全解
Linux相关知识点可以通过点击以下链接进行学习一起加油!初识指令指令进阶权限管理yum包管理与vim编辑器GCC/G编译器make与Makefile自动化构建GDB调试器与Git版本控制工具Linux下进度条 冯诺依曼体系是现代计算机设计的基石,其统一存储和顺序执行理念推动…...
【深度学习】 UNet详解
UNet 是一种经典的卷积神经网络(Convolutional Neural Network, CNN)架构,专为生物医学图像分割任务设计。该模型于 2015 年由 Olaf Ronneberger 等人在论文《U-Net: Convolutional Networks for Biomedical Image Segmentation》中首次提出&…...
“深入浅出”系列之算法篇:(2)openCV、openMV、openGL
OpenCV是一个的跨平台计算机视觉库,可以运行在Linux囚、Windows 和Mac OS操作系统上。它轻量级而且高效,由一系列 C函数和少量C类构成,同时也提供了Python 接口,实现了图像处理和计算机视觉方面的很多通用算法。 OpenMV是一个开源,低成本&am…...
低代码系统-产品架构案例介绍、得帆云(八)
产品名称 得帆云DeCode低代码平台-私有化 得帆云DeMDM主数据管理平台 得帆云DeCode低代码平台-公有云 得帆云DePortal企业门户 得帆云DeFusion融合集成平台 得帆云DeHoop数据中台 名词 概念 云原生 指自己搭建的运维平台,区别于阿里云、腾讯云 Dehoop 指…...
web3py+flask+ganache的智能合约教育平台
最近在学习web3的接口文档,使用web3pyflaskganache写了一个简易的智能合约教育平台,语言用的是python,ganche直接使用的本地区块链网络,用web3py进行交互。 代码逻辑不难,可以私信或者到我的闲鱼号夏沫mds获取我的代码…...
(长期更新)《零基础入门 ArcGIS(ArcMap) 》实验六----流域综合处理(超超超详细!!!)
流域综合处理 流域综合治理是根据流域自然和社会经济状况及区域国民经济发展的要求,以流域水流失治理为中心,以提高生态经济效益和社会经济持续发展为目标,以基本农田优化结构和高效利用及植被建设为重点,建立具有水土保持兼高效生态经济功能的半山区流域综合治理模式。数字高程…...
基于 WPF 平台使用纯 C# 实现动态处理 json 字符串
一、引言 在当今的软件开发领域,数据的交换与存储变得愈发频繁,JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,以其简洁、易读、便于解析和生成的特点,被广泛应用于各种应用程序中。在 W…...
DRF开发避坑指南01
在当今快速发展的Web开发领域,Django REST Framework(DRF)以其强大的功能和灵活性成为了众多开发者的首选。然而,错误的使用方法不仅会导致项目进度延误,还可能影响性能和安全性。本文将从我个人本身遇到的相关坑来给大…...
WordPress免费证书插件
为了在您的网站上启用HTTPS,您可以使用本插件快速获取Let’s Encrypt免费证书。 主要功能: 支持快速申请Let’s Encrypt免费证书支持通配符证书申请,每个证书最多可以绑定100个域名支持自动续期证书支持重颁发证书,证书过期或失…...
MongoDB平替数据库对比
背景 项目一直是与实时在线监测相关,特点数据量大,读写操作大,所以选用的是MongoDB。但按趋势来讲,需要有一款国产数据库可替代,实现信创要求。选型对比如下 1. IoTDB 这款是由清华大学主导的开源时序数据库&#x…...
ANSYS学习笔记(十)网格质量的诊断和提高
网格质量的好坏不能单纯只看meshing给出的网格质量结果,要根据实际的计算物理场景来判断,需要求解的地方物理量大梯度的位置网格越密越好。 网格质量:在有限网格数量限制下,离散误差小的网格是好网格,是高质量网格。网…...
能量提升法三:赞美
前情回顾: 《能量提升法二:感恩》 片段:“感恩,就像是在跟世界说:谢谢你,我收到了,我很喜欢,请多来点” 把它归还人海,就当作每一个人,都有可能是曾经帮助…...
C++中函数返回值当引用
文章目录 一、概述二、返回值当引用的基本语法三、返回局部变量的引用四、返回引用的常见用途五、返回右值引用六、总结 一、概述 在 C 中,函数返回值当引用(即返回引用)是一个常见的编程技巧。它可以让你返回一个函数内部的局部变量或对象的…...
27. C语言 强制类型转换详解
本章目录: 前言强制类型转换(Type Casting)强制类型转换的语法示例1:将整数转换为浮点数输出结果: 代码解析: 整数提升(Integer Promotion)示例2:整数提升输出结果: 代码…...
Linux 命令之技巧(Tips for Linux Commands)
Linux 命令之技巧 简介 Linux 是一种免费使用和自由传播的类Unix操作系统,其内核由林纳斯本纳第克特托瓦兹(Linus Benedict Torvalds)于1991年10月5日首次发布。Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户…...
freeswitch在centos上编译过程
操作系统:centos9-last usr/local/freeswitch/bin/freeswitch -version FreeSWITCH version: 1.10.13-devgit~20250125T131725Z~3f1e4bf90a~64bit (git 3f1e4bf 2025-01-25 13:17:25Z 64bit)vi /etc/ssh/sshd_config ip a nmtui reboot ip a curl -o /etc/pki/rpm-…...
快速入门Flink
Flink是新一代实时计算平台,采用原生的流处理系统,保证了低延迟性,在API和容错上也是做的相当完善,本文将从架构、组件栈、安装、入门程序等进行基础知识的分析,帮助大家快速对Flink有一个了解。 一.简介 1.是什么 Ap…...
c++ list
1.构造函数 构造函数 // list<T> lst; // list(beg, end); // 区间构造 // list(n, elem); // 元素构造 // list(const list &lst); // 拷贝构造#include <iostream> #include <fstream> #include <string> #include <list> using name…...
Vue 3 + TypeScript 实现父子组件协同工作案例解析
引言 在现代的前端开发中,Vue.js 作为一款流行的渐进式 JavaScript 框架,为我们构建交互式用户界面提供了强大的支持。Vue 3 的推出带来了许多新特性,尤其是组合式 API 的引入,让代码的组织和复用更加灵活。同时,TypeS…...
深度剖析C++17中的std::optional:处理可能缺失值的利器
文章目录 一、基本概念与设计理念二、构建与初始化(一)默认构造(二)值初始化(三)使用std::make_optional(四)使用std::nullopt 三、访问值(一)value()&#x…...
【ArcGIS微课1000例】0141:提取多波段影像中的单个波段
文章目录 一、波段提取函数二、加载单波段导出问题描述:如下图所示,img格式的时序NDVI数据有24个波段。现在需要提取某一个波段,该怎样操作? 一、波段提取函数 首先加载多波段数据。点击【窗口】→【影像分析】。 选择需要处理的多波段影像,点击下方的【添加函数】。 在多…...
一分钟搭建promehteus+grafana+alertmanager监控平台
为什么要自己搭建一个监控平台 平时进行后端开发,特别是微服务的后端可开发,一定少不了对接监控平台,但是平时进行一些小功能的测试又没有必要每次都手动安装那么多软件进行一个小功能的测试,这里我使用docker-compose搭建了一个…...
Transfoemr的解码器(Decoder)与分词技术
在自然语言处理(NLP)领域,解码器(Decoder)和分词技术是两个至关重要的概念。解码器是序列生成任务的核心组件,而分词则是将文本数据转换为可处理形式的基础步骤。 一、解码器(Decoder&…...
LeetCode100之在排序数组中查找元素的第一个和最后一个位置(34)--Java
1.问题描述 给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target,返回 [-1, -1]。 你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题 示例1 输入…...
数字人+展厅应用方案:开启全新沉浸式游览体验
随着人们生活质量的不断提升,对于美好体验的追求日益增长。在展厅展馆领域,传统的展示方式已难以满足大众日益多样化的需求。而通过将数字人与展厅进行深度结合,可以打造数字化、智能化新型展厅,不仅能提升展示效果,还…...
echo ‘export PATH=/usr/local/bin:$PATH‘ >> ~/.bashrc这个和直接添加到/etc/profile有什么区别
echo export PATH/usr/local/bin:$PATH >> ~/.bashrc 和直接添加到 /etc/profile 都是用于修改 PATH 环境变量,但它们适用的范围和效果有所不同: 1. 修改 ~/.bashrc 文件 作用范围:~/.bashrc 是针对当前用户的配置文件,它…...
kafka消费者详细介绍(超级详细)
文章目录 一、Kafka 消费者与消费者组1.1 Kafka 消费者(Consumer)概述1.1.1 消费者工作流程1.1.2 消费者的关键配置 1.2 Kafka 消费者组(Consumer Group)概述1.2.1 消费者组的工作原理1.2.2 消费者组的优点1.2.3 消费者组的再均衡…...
《剪映5.9官方安装包》免费自动生成字幕
(避免失效建议存自己网盘后下载)剪映5.9官方Win.Mac 链接:https://pan.xunlei.com/s/VOHc-Fg2XRlD50MueEaOOeW1A1?pwdawtt# 官方唯一的免费版,Win和Mac都有,此版本官方已下架,觉得有用可转存收藏…...
CAS是什么?ABA会带来什么影响?怎么解决ABA问题?
前言 在高并发开发中,CAS(比较并交换)是一种常用的无锁操作,因其高效性而被广泛应用。然而,实际工作中常会遇到ABA问题,导致数据更新异常或逻辑错误。理解CAS的原理及ABA问题的解决方法,有助于…...
智能调度体系与自动驾驶技术优化运输配送效率的研究——兼论开源AI智能名片2+1链动模式S2B2C商城小程序的应用潜力
摘要:随着全球化和数字化进程的加速,消费者需求日益呈现出碎片化和个性化的趋势,这对物流运输行业提出了前所未有的挑战。传统的物流调度体系与调度方式已难以满足当前复杂多变的物流需求,因此,物流企业必须积极引入大…...
方豆子(递归)
方豆子 思路:很典的一道递归题,但当时没想到怎么递归/(ㄒoㄒ)/~~。赛后看了大佬的讲解知道要将这个图形看成由四个小正方形组成的大正方形,递归参数可以设置成(r1,c1,r2,c2,good)表示正方形的左上角坐标和右下角坐标以及当前这个正…...
Go语言入门指南(二): 数据类型
文章创作不易,麻烦大家点赞关注转发一键三连。 在上一篇文章,我们已经完成了开发环境的搭建,成功创建了第一个“Hello, World”程序,并且对变量的声明和初始化有了初步的认识。在这篇文章中,我们将主要介绍Go语言的数据…...
Django ORM解决Oracle表多主键的问题
现状 以Django 3.2为例 Django ORM 设计为默认使用单一主键(通常是自增的 id 字段),这一选择主要基于以下核心原因: 简化ORM设计与操作 统一访问方式外键关联简化 避免歧义冲突 主键语义明确防止隐式依赖 性能与数据库兼容 索引…...
学习数据结构(2)空间复杂度+顺序表
1.空间复杂度 (1)概念 空间复杂度也是一个数学表达式,表示一个算法在运行过程中根据算法的需要额外临时开辟的空间。 空间复杂度不是指程序占用了多少bytes的空间,因为常规情况每个对象大小差异不会很大,所以空间复杂…...
实验一---典型环节及其阶跃响应---自动控制原理实验课
一 实验目的 1.掌握典型环节阶跃响应分析的基本原理和一般方法。 2. 掌握MATLAB编程分析阶跃响应方法。 二 实验仪器 1. 计算机 2. MATLAB软件 三 实验内容及步骤 利用MATLAB中Simulink模块构建下述典型一阶系统的模拟电路并测量其在阶跃响应。 1.比例环节的模拟电路 提…...
从零推导线性回归:最小二乘法与梯度下降的数学原理
欢迎来到我的主页:【Echo-Nie】 本篇文章收录于专栏【机器学习】 本文所有内容相关代码都可在以下仓库中找到: Github-MachineLearning 1 线性回归 1.1 什么是线性回归 线性回归是一种用来预测和分析数据之间关系的工具。它的核心思想是找到一条直…...
OpenSIPS-从安装部署开始认识一个组件
前期讲到了Kamailio,它是一个不错的开源SIP(Session Initiation Protocol)服务器,主要用于构建高效的VoIP(Voice over IP)平台以及即时通讯服务。但是在同根同源(OpenSER)的分支上&a…...
数据结构(树)
每一个节点包含:父节点地址 值 左子节点地址 右子节点地址 如果一个节点不含有:父节点地址或左子节点地址 右子节点地址就记为null 二叉树 度:每一个节点的子节点数量 二叉树中,任意节点的度<2 树的结构: 二叉查…...
[Dialog屏幕开发] 设置搜索帮助
阅读该篇文章之前,可先阅读下述资料 [Dialog屏幕开发] 屏幕绘制(使用向导创建Tabstrip Control标签条控件)https://blog.csdn.net/Hudas/article/details/145372195?spm1001.2014.3001.5501https://blog.csdn.net/Hudas/article/details/145372195?spm1001.2014.…...
C语言从入门到进阶
视频:https://www.bilibili.com/video/BV1Vm4y1r7jY?spm_id_from333.788.player.switch&vd_sourcec988f28ad9af37435316731758625407&p23 //枚举常量 enum Sex{MALE,FEMALE,SECRET };printf("%d\n", MALE);//0 printf("%d\n", FEMALE…...
Node.js下载安装及环境配置教程 (详细版)
Node.js:是一个基于 Chrome V8 引擎的 JavaScript 运行时,用于构建可扩展的网络应用程序。Node.js 使用事件驱动、非阻塞 I/O 模型,使其非常适合构建实时应用程序。 Node.js 提供了一种轻量、高效、可扩展的方式来构建网络应用程序࿰…...
Mac Electron 应用签名(signature)和公证(notarization)
在MacOS 10.14.5之后,如果应用没有在苹果官方平台进行公证notarization(我们可以理解为安装包需要审核,来判断是否存在病毒),那么就不能被安装。当然现在很多人的解决方案都是使用sudo spctl --master-disable,取消验证模式&#…...
redis安装 windows版本
下载 github下载5.x版本redis 安装以及启动 解压文件,目标如下 进入cmd至安装路径 执行如下命令启动redis redis-server.exe redis.windows.conf 进入redis,另外启动cmd在当前目录执行进入redis 服务 redis-cli 测试命令 至此安装成功,但是这只是…...
关联传播和 Python 和 Scikit-learn 实现
文章目录 一、说明二、什么是 Affinity Propagation。2.1 先说Affinity 传播的工作原理2.2 更多细节2.3 传播两种类型的消息2.4 计算责任和可用性的分数2.4.1 责任2.4.2 可用性分解2.4.3 更新分数:集群是如何形成的2.4.4 估计集群本身的数量。 三、亲和力传播的一些…...
若依基本使用及改造记录
若依框架想必大家都了解得不少,不可否认这是一款及其简便易用的框架。 在某种情况下(比如私活)使用起来可谓是快得一匹。 在这里小兵结合自身实际使用情况,记录一下我对若依框架的使用和改造情况。 一、源码下载 前往码云进行…...
c语言网 1127 尼科彻斯定理
原题 题目描述 验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。 输入格式 任一正整数 输出格式 该数的立方分解为一串连续奇数的和 样例输入 13 样例输出 13*13*132197157159161163165167169171173175177179181 #include<ios…...
能说说MyBatis的工作原理吗?
大家好,我是锋哥。今天分享关于【Redis为什么这么快?】面试题。希望对大家有帮助; 能说说MyBatis的工作原理吗? MyBatis 是一款流行的持久层框架,它通过简化数据库操作,帮助开发者更高效地与数据库进行交互。MyBatis…...
卡特兰数学习
1,概念 卡特兰数(英语:Catalan number),又称卡塔兰数,明安图数。是组合数学中一种常出现于各种计数问题中的数列。它在不同的计数问题中频繁出现。 2,公式 卡特兰数的递推公式为:f(…...