Linux migrate_type初步探索
1、基础知识
我们都知道Linux内存组织管理结构架构,顶层是struct pglist_data
,然后再到struct zone
,最后是struct page
。大概的管理结构是这样的:
根据物理内存的地址范围可划分不同的zone,每个zone里的内存由buddy系统所管理,buddy系统管理着不同order大小的链表,在每个不同大小order链表的内部,又根据migrate_type类型进行分类保存。
2、migrate_type作用
为了更好的管理物理内存,操作系统进一步抽象出页块的概念,通常一个页块的大小是2^(MAX_ORDER-1)个页面(4MB)。每个页块对应一个迁移类型migrate_type
,buddy系统中的页面,根据其所在migrate_type
链表,可知道该页是属于哪个migrate_type
的页块。
问: 为什么要抽象出页块,并给页块指定迁移类型呢?
答: 因为要实现页面规整功能。在buddy系统中的页面不断被线程所申请使用,页面外部碎片化就会很严重,很容易就无法分配出连续大order的页面,而且我们也无法进行页面规整,因为我们不知道已分配出的页面是否可以通过将数据迁移到其他页面进行回收。但是当我们有了迁移类型后,我们完全可以知道已分配出的页面数据什么迁移类型,是否支持回收。
例如:当buddy系统中存留page0、page2、page3,page1已经被分配出去,但是page1的所属页块的迁移类型是MIGRATE_MOVABLE
,如果我们想用page0-3满足作为order2的分配请求,我们完全可以将page1的数据迁移到page5上,同时再将page1上的映射关系也转移到page5上,这样page1就可以回收回来,与其他page形成order2的页面,满足order2的分配请求。
3、页块的迁移类型存储
我们上面了解到每个页块对应一个迁移类型,这个迁移类型是在哪里存储的呢?另外,如何通过pfn找到对应的页块,进而获取到迁移类型呢?
先明确两个特点:
1、大部分物理内存页面一开始存放在MIGRATE_MOVABLE
链表中
2、大部分物理内存页面初始化时存放在order为10的链表中
当我们要使用MIGRATE_UNMOVABLE
的页面时,会fallback到MIGRATE_MOVABLE
,并将整个页块的迁移类型都改变为MIGRATE_UNMOVABLE
。
start_kernel()
-> setup_arch()
--> bootmem_init()
---> zone_sizes_init()
----> free_area_init_node()
-----> free_area_init_core()
/** Set up the zone data structures:* - mark all pages reserved* - mark all memory queues empty* - clear the memory bitmaps** NOTE: pgdat should get zeroed by caller.* NOTE: this function is only called during early init.*/
static void __init free_area_init_core(struct pglist_data *pgdat)
{enum zone_type j;int nid = pgdat->node_id;pgdat_init_internals(pgdat);pgdat->per_cpu_nodestats = &boot_nodestats;for (j = 0; j < MAX_NR_ZONES; j++) { // 遍历当前pglist_data所有的zonestruct zone *zone = pgdat->node_zones + j;unsigned long size, freesize, memmap_pages;unsigned long zone_start_pfn = zone->zone_start_pfn;...set_pageblock_order(); // 配置页块大小setup_usemap(pgdat, zone, zone_start_pfn, size); // 设置当前zone内页块的迁移类型保存空间init_currently_empty_zone(zone, zone_start_pfn, size);memmap_init(size, nid, j, zone_start_pfn); // 初始化当前zone}
}
3.1 首先来看一下set_pageblock_order()
/* Initialise the number of pages represented by NR_PAGEBLOCK_BITS */
void __init set_pageblock_order(void)
{unsigned int order;/* Check that pageblock_nr_pages has not already been setup */if (pageblock_order)return;if (HPAGE_SHIFT > PAGE_SHIFT)order = HUGETLB_PAGE_ORDER;elseorder = MAX_ORDER - 1;/** Assume the largest contiguous order of interest is a huge page.* This value may be variable depending on boot parameters on IA64 and* powerpc.*/pageblock_order = order;
}
在没开启HUGETLB_PAGE
特性,pageblock_order就为MAX_ORDER-1,也就是10。
3.2 再来看一下setup_usemap()
zone->pageblock_flags
保存当前zone内所有页块的迁移类型信息:
static void __ref setup_usemap(struct pglist_data *pgdat,struct zone *zone,unsigned long zone_start_pfn,unsigned long zonesize)
{// 这里计算要保存zone所有页块对应的迁移类型需要多大的空间unsigned long usemapsize = usemap_size(zone_start_pfn, zonesize);zone->pageblock_flags = NULL;if (usemapsize) {// 为迁移类型块所占空间分配内存zone->pageblock_flags =memblock_alloc_node(usemapsize, SMP_CACHE_BYTES,pgdat->node_id);if (!zone->pageblock_flags)panic("Failed to allocate %ld bytes for zone %s pageblock flags on node %d\n",usemapsize, zone->name, pgdat->node_id);}
}// pageblock_nr_pages表示一个页块包含的页面数量
#define pageblock_nr_pages (1UL << pageblock_order)/** Calculate the size of the zone->blockflags rounded to an unsigned long* Start by making sure zonesize is a multiple of pageblock_order by rounding* up. Then use 1 NR_PAGEBLOCK_BITS worth of bits per pageblock, finally* round what is now in bits to nearest long in bits, then return it in* bytes.*/
static unsigned long __init usemap_size(unsigned long zone_start_pfn, unsigned long zonesize)
{unsigned long usemapsize;// 这两步主要是进行对齐,得到该zone包含的所有页块的页面总数,对齐按照pageblock_nr_pages去向上取整,将整个zone空间划分成一个个页块大小,不足一个页块的部分,也作为一个页块处理zonesize += zone_start_pfn & (pageblock_nr_pages-1);usemapsize = roundup(zonesize, pageblock_nr_pages);// 得到zone存放的页块总数usemapsize = usemapsize >> pageblock_order;// 每个页块的迁移类型所占空间是NR_PAGEBLOCK_BITS个位,这个宏的值是4,也就是说一个页块的迁移类型需要4个bit来表示usemapsize *= NR_PAGEBLOCK_BITS;// 8表示一个字节包含8个bit,sizeof(unsigned long)表示一个unsigned long类型里有几个字节,其实这里就是计算zone内所有页块的迁移类型需要多大的内存空间(需要多少个unsigned long存储)usemapsize = roundup(usemapsize, 8 * sizeof(unsigned long));// / 8 因为一个unsigned long代表8个字节,所以除以8,转换成所需字节数量return usemapsize / 8;
}
3.3 最后看一下memmap_init()
void __meminit __weak memmap_init(unsigned long size, int nid,unsigned long zone,unsigned long range_start_pfn)
{unsigned long start_pfn, end_pfn;unsigned long range_end_pfn = range_start_pfn + size;int i;// 遍历该zone的合法物理内存区域for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) {start_pfn = clamp(start_pfn, range_start_pfn, range_end_pfn);end_pfn = clamp(end_pfn, range_start_pfn, range_end_pfn);if (end_pfn > start_pfn) {size = end_pfn - start_pfn;// 初始化该区域,并且设置该区域的页块迁移类型是MIGRATE_MOVABLEmemmap_init_zone(size, nid, zone, start_pfn,MEMINIT_EARLY, NULL, MIGRATE_MOVABLE);}}
}/** Initially all pages are reserved - free ones are freed* up by memblock_free_all() once the early boot process is* done. Non-atomic initialization, single-pass.** All aligned pageblocks are initialized to the specified migratetype* (usually MIGRATE_MOVABLE). Besides setting the migratetype, no related* zone stats (e.g., nr_isolate_pageblock) are touched.*/
void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,unsigned long start_pfn,enum meminit_context context,struct vmem_altmap *altmap, int migratetype)
{unsigned long pfn, end_pfn = start_pfn + size;struct page *page;if (highest_memmap_pfn < end_pfn - 1)highest_memmap_pfn = end_pfn - 1;
...for (pfn = start_pfn; pfn < end_pfn; ) {/** There can be holes in boot-time mem_map[]s handed to this* function. They do not exist on hotplugged memory.*/if (context == MEMINIT_EARLY) {if (overlap_memmap_init(zone, &pfn))continue;if (defer_init(nid, pfn, end_pfn))break;}// 根据pfn获取到struct page对象page = pfn_to_page(pfn);__init_single_page(page, pfn, zone, nid);if (context == MEMINIT_HOTPLUG)__SetPageReserved(page);/** Usually, we want to mark the pageblock MIGRATE_MOVABLE,* such that unmovable allocations won't be scattered all* over the place during system boot.*/// 如果该pfn是以页块包含页面数量对齐的话if (IS_ALIGNED(pfn, pageblock_nr_pages)) {// 设置迁移类型,该迁移类型是MIGRATE_MOVABLEset_pageblock_migratetype(page, migratetype);cond_resched();}pfn++;}
}void set_pageblock_migratetype(struct page *page, int migratetype)
{if (unlikely(page_group_by_mobility_disabled &&migratetype < MIGRATE_PCPTYPES))migratetype = MIGRATE_UNMOVABLE;set_pfnblock_flags_mask(page, (unsigned long)migratetype,page_to_pfn(page), MIGRATETYPE_MASK);
}/* Return a pointer to the bitmap storing bits affecting a block of pages */
static inline unsigned long *get_pageblock_bitmap(struct page *page,unsigned long pfn)
{
#ifdef CONFIG_SPARSEMEM // 如果开了SPARSMEM布局,则走该路径return section_to_usemap(__pfn_to_section(pfn));
#else // 否则使用zone->pageblock_flagsreturn page_zone(page)->pageblock_flags;
#endif /* CONFIG_SPARSEMEM */
}static inline int pfn_to_bitidx(struct page *page, unsigned long pfn)
{
#ifdef CONFIG_SPARSEMEMpfn &= (PAGES_PER_SECTION-1);
#elsepfn = pfn - round_down(page_zone(page)->zone_start_pfn, pageblock_nr_pages);
#endif /* CONFIG_SPARSEMEM */// 根据pfn获取到所处的页块号,每个页块号对应的迁移类型需要NR_PAGEBLOCK_BITS个bit存储,* NR_PAGEBLOCK_BITS获取到该页块的迁移类型保存的起始bit位置return (pfn >> pageblock_order) * NR_PAGEBLOCK_BITS;
}/*** set_pfnblock_flags_mask - Set the requested group of flags for a pageblock_nr_pages block of pages* @page: The page within the block of interest* @flags: The flags to set* @pfn: The target page frame number* @mask: mask of bits that the caller is interested in*/
void set_pfnblock_flags_mask(struct page *page, unsigned long flags,unsigned long pfn,unsigned long mask)
{unsigned long *bitmap;unsigned long bitidx, word_bitidx;unsigned long old_word, word;BUILD_BUG_ON(NR_PAGEBLOCK_BITS != 4);BUILD_BUG_ON(MIGRATE_TYPES > (1 << PB_migratetype_bits));// 获取zone->pageblock_flags,保存该zone所有页块的迁移类型内存区域bitmap = get_pageblock_bitmap(page, pfn);// 找到该pfn应保存该页块迁移类型的起始bit位置bitidx = pfn_to_bitidx(page, pfn);word_bitidx = bitidx / BITS_PER_LONG;bitidx &= (BITS_PER_LONG-1);VM_BUG_ON_PAGE(!zone_spans_pfn(page_zone(page), pfn), page);mask <<= bitidx;flags <<= bitidx;// 保存迁移类型操作word = READ_ONCE(bitmap[word_bitidx]);for (;;) {old_word = cmpxchg(&bitmap[word_bitidx], word, (word & ~mask) | flags);if (word == old_word)break;word = old_word;}
}
关于migrate_type初步探索先到这里,感谢各位读者浏览!!!
预知后续如何,请看下个博文的分析。
相关文章:
Linux migrate_type初步探索
1、基础知识 我们都知道Linux内存组织管理结构架构,顶层是struct pglist_data,然后再到struct zone,最后是struct page。大概的管理结构是这样的: 根据物理内存的地址范围可划分不同的zone,每个zone里的内存由buddy…...
i.MX 6ULL 裸机 IAR 环境安装
一. IAR 的安装请自行搜索 二. 使用最新版本的 IAR,需要修改 SDK 1. 在 SDK 的 core_ca7.h 加上 #include "intrinsics.h" /* IAR Intrinsics */ 2. debug 时需要修改每个工程下的 ddr_init.jlinkscript,参考链接 Solved: How to conn…...
cmake进阶:文件操作
一. 简介 前面几篇文章学习了 cmake的文件操作,写文件,读文件。文章如下: cmake进阶:文件操作之写文件-CSDN博客 cmake进阶:文件操作之读文件-CSDN博客 本文继续学习文件操作。主要学习 文件重命名,删…...
在UI界面中播放视频_unity基础开发教程
在UI界面中播放视频_unity基础开发教程 前言操作步骤结语 前言 之前我写过一篇在场景中播放视频的文章,但是在开发中有时候也会在UI的界面中播放视频,这期我们做一下在UI的界面中播放视频。 操作步骤 首先在场景中创建一个Raw Image,UI->…...
TypeScipt 联合类型 | 号的使用
联合类型有两种使用方法: 一种类型中多个可能的值。具有多种不同的类型中的一种。 一种类型中多个可能的值。 type isAye true | false;const aye:isAye true; const aye1:isAye false; const aye2:isAye 3; // Type number is not assignable to type isAye…...
MATLAB 变换
MATLAB 变换(Transforms) MATLAB提供了用于处理诸如Laplace和Fourier变换之类的变换的命令。转换在科学和工程中用作简化分析和从另一个角度查看数据的工具。 例如,傅立叶变换允许我们将表示为时间函数的信号转换为频率函数。拉普拉斯变换使…...
【005_音频开发_基础篇_ALSA_Codec_驱动-MA120x0P功放】
005_音频开发_基础篇_ALSA_Codec_驱动-MA120x0P功放 文章目录 005_音频开发_基础篇_ALSA_Codec_驱动-MA120x0P功放创作背景MA120X0P输出模式BTLSEPBTLSEBTL 硬件配置方式/硬件Limiter限幅器限幅器作用过程 主要寄存器操作指令 ma120x0p.cma120x0p.h 创作背景 学历代表过去、能…...
2、FreeCAD模块与核心架构总结
FreeCAD作为一个开源的3D建模软件,其内部架构由多个模块组成,这些模块共同协作以支持软件的各种功能。本总结将基于提供的参考文档,对FreeCAD的核心模块、架构特性以及启动过程进行翻译和详细阐述。 核心模块概览 FreeCAD的核心模块主要包括…...
MySQL为什么默认引擎是InnoDB?
因为InnoDB特别强大,其支持很多东西 1.支持事务: 意味着对于一个复杂的SQL语句要么全部执行成功,要么全部失败,因为其底层是原子性的 2.支持并发(行级并发) 意味着面对高并发,多个用户可以同时访问一个表的不同行,不同行之间上锁,而不是给一个表上锁,这样就提高了高并发的性能和…...
K8s: Helm搭建mongodb集群(1)
mongodb 集群搭建 mongdb 部署前 需要创建 pvc, pv 和 sc,如果在云上会自动创建helm 应用中心: https://artifacthub.io 1 )Helm 安装 mongodb A. 无本地存储配置,重启数据消失 在 https://artifacthub.io/packages/helm/bitnami/mongodb…...
应用分层和企业规范
目录 一、应用分层 1、介绍 (1)为什么需要应用分层? (2)如何分层?(三层架构) MVC 和 三层架构的区别和联系 高内聚: 低耦合: 2、代码重构 controlle…...
Flutter笔记:Widgets Easier组件库(1)使用各式边框
Flutter笔记 Widgets Easier组件库(1):使用边框 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress o…...
OpenHarmony实战开发-上传文件
Web组件支持前端页面选择文件上传功能,应用开发者可以使用onShowFileSelector()接口来处理前端页面文件上传的请求。 下面的示例中,当用户在前端页面点击文件上传按钮,应用侧在onShowFileSelector()接口中收到文件上传请求,在此接…...
外贸企业邮箱是什么?做外贸企业邮箱哪个好?
外贸企业邮箱是什么?外贸企业在进行跨国沟通时必不可少的工具就是外贸企业邮箱,外贸企业邮箱需要具备的条件就是海外邮件抵达率高、安全稳定、多语言沟通。而我们又怎么选择一个适合的外贸企业邮箱呢?小编今天带您一起了解。 一、外贸企业邮…...
写一个简单的程序
思路分析: 1. 导入必要的库 首先,确保你的项目中包含了AWT或Swing库,因为我们将使用它们来创建图形界面。 import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import j…...
CentOS安装Docker指南
Docker安装与配置教程 Docker作为一种轻量级的虚拟化技术,在现代软件开发和运维中扮演着重要的角色。下面,我将以技术博主的身份,向大家详细介绍如何在Linux系统上安装和配置Docker,特别是如何设置Docker的监听地址和端口&#x…...
python绘图(pandas)
matplotlib绘图 import pandas as pd abs_path rF:\Python\learn\python附件\pythonCsv\data.csv df pd.read_csv(abs_path, encodinggbk) # apply根据多列生成新的一个列的操作,用apply df[new_score] df.apply(lambda x : x.数学 x.语文, axis1)# 最后几行 …...
Android(Java)项目支持Kotlin语言开发
Android(Java)项目通过相关Kotlin设置后,允许同时使用Java语言和Kotlin语言进行开发代码的。 示例环境: Android Studio Giraffe | 2022.3.1 Patch 3 Java 8 Kotlin 1.9.20 设置Kotlin选项: 第一步:在项…...
Terraform创建模块
模块就是包含一组Terraform代码的文件夹,可以通过模块直接使用别人编写好的Terraform代码来创建资源。 Terraform模块是编写高质量Terraform代码,提升代码复用性的重要手段,可以说,一个成熟的生产环境应该是由数个可信成熟的模块组…...
《华为鸿蒙:从备胎到主角的崛起之路》
华为鸿蒙操作系统的发展历程可以追溯到 2012 年,当时华为开始规划自有操作系统鸿蒙 OS。然而,直到 2019 年 5 月,鸿蒙才正式进入开发阶段。 2019 年 8 月 9 日,华为正式发布了鸿蒙操作系统。 鸿蒙系统的首个版本是于 2019 年推出…...
FPGA学习笔记(2)——Verilog语法及ModelSim使用
1.1 语法 1、赋值语句 和 < 为阻塞赋值,当该语句结束时,下一个语句才开始执行,串行执行 < 为非阻塞幅值,该语句和整个语句块同时执行,并行执行 1.2 ModelSim使用 1、修改源文件路径:File -> …...
2024年十大AI工具,让你的工作学习效率飞跃
在这个迅速变化的数字时代,人工智能技术正在以前所未有的速度发展和革新。AI技术不仅深入科研、医疗和教育等领域,还广泛应用于日常生活和商业活动中。本文梳理了2024年十款最好用的AI工具,它们各有特色,能极大提升工作效率和生活…...
linux之NAMP
linux之NAMP Nmap(Network Mapper)是一个开源的网络扫描和安全审计工具。它被设计用来快速地扫描大型网络,尽管它也可以对单个主机进行有效的扫描。Nmap利用原始IP数据包以多种方式探测目标网络上的主机、服务(应用程序名称和版本…...
uniapp 禁止截屏(应用内,保护隐私)插件 Ba-ScreenShot
禁止截屏(应用内,保护隐私) Ba-ScreenShot 简介(下载地址) Ba-ScreenShot 是一款uniapp禁止应用内截屏的插件,保护隐私,支持禁止截屏、放开截屏 截图展示 也可关注博客,实时更新最…...
数字电路-5路呼叫显示电路和8路抢答器电路
本内容涉及两个电路,分别为5路呼叫显示电路和8路抢答器电路,包含Multisim仿真原文件,为掌握FPGA做个铺垫。紫色文字是超链接,点击自动跳转至相关博文。持续更新,原创不易! 目录: 一、5路呼叫显…...
C++中的函数签名
前言: 很多C初学者会发现函数签名这一概念在C的学习过程中经常出现,然而很多人往往不太了解函数签名包括些什么,本文章将从一个初学者的角度出发,详细解释函数签名这一概念。 在C中,函数签名用于唯一地识别函数重载。…...
Mac brew安装Redis之后更新配置文件的方法
安装命令 brew install redis 查看安装位置命令 brew list redis #查看redis安装的位置 % brew list redis /usr/local/Cellar/redis/6.2.5/.bottle/etc/ (2 files) /usr/local/Cellar/redis/6.2.5/bin/redis-benchmark /usr/local/Cellar/redis/6.2.5/bin/redis-check-ao…...
安卓应用开发(一):工具与环境
开发工具 Android Studio,用于开发 Android 应用的官方集成开发环境 (IDE)。包括以下功能: 基于Gradle的构建系统 gradle是一个项目构建工具,将源工程打包构建为apk 安卓模拟器统一环境代码编辑模拟器实时更新Github集成Lint功能࿰…...
基于springboot+vue+Mysql的在线动漫信息平台
开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…...
C++设计模式-结构型设计模式
写少量的代码来应对未来需求的变化。 单例模式 定义 保证一个类仅有一个实例,并提供一个该实例的全局访问点。——《设计模式》GoF 解决问题 稳定点: 类只有一个实例,提供全局的访问点(抽象) 变化点:…...
open-webui+ollama本地部署Llama3
前言 Meta Llama 3 是由 Meta 公司发布的下一代大型语言模型,拥有 80 亿和 700 亿参数两种版本,号称是最强大的开源语言模型。它在多个基准测试中超越了谷歌的 Gemma 7B 和 Mistral 7B Instruct 模型。 安装 1.gpt4all https://github.com/nomic-ai/…...
个人对行为型设计模式的理解 @by_TWJ
目录 1. 访问者模式2. 迭代器模式3. 观察者模式4. 模板模式5. 状态模式6. 备忘录模式7. 策略模式8. 解释器模式9. 责任链模式10. 命令模式11. 中介者模式 研究了一下,我为了方便理解,对它们进行了分类: 针对请求者与执行者关系方面 1对多 - 责…...
苹果挖走大量谷歌人才,建立神秘人工智能实验室;李飞飞创业成立「空间智能」公司丨 RTE 开发者日报 Vol.197
开发者朋友们大家好: 这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real Time Engagement) 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…...
行业唯一!易保全牵头编制的《区块链数据访问安全技术通则》发布
近日,易保全牵头参与编制的《区块链数据访问安全技术通则》经中国国际经济技术合作促进会正式发布,为中国区块链数据安全技术提供了标准参考。 易保全作为牵头起草单位、易保全CEO兼董事长刘刚担任主要起草人参与其中,在区块链技术安全风险…...
Rust Rocket创建第一个hello world的Web程序 Rust Rocket开发常用网址和Rust常用命令
一、Rust Rocket简介 Rust Rocket 是一个用 Rust 语言编写的 Web 应用框架,它结合了 Rust 的安全性和性能优势,以及 Web 开发的便利性。以下是 Rust Rocket 框架的一些优点: 安全性:Rust 是一种注重安全性的编程语言,…...
第G9周:ACGAN理论与实战
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制🚀 文章来源:K同学的学习圈子 上一周已经给出代码,需要可以跳转上一周的任务 第G8周:ACGAN任…...
Linux网络部分——DNS域名解析服务
目录 1. 域名结构 2. 系统根据域名查找IP地址的过程 3.DNS域名解析方式 4.DNS域名解析的工作原理【☆】 5.域名解析查询方式 6.搭建主从DNS域名服务器 ①初始化操作主服务器和从服务器,安装BIND软件 ②修改主服务器的主配置文件、区域配置文件、区域数…...
预处理详解
乐观学习,乐观生活,才能不断前进啊!!! 我的主页:optimistic_chen 我的专栏:c语言 点击主页:optimistic_chen和专栏:c语言, 创作不易,大佬们点赞鼓…...
Python的创建和使用自定义模块
Python 的模块是组织代码的基本单元,它可以包含变量、函数、类等,并且可以被其他 Python 程序引用和重用。除了使用 Python 提供的标准库和第三方库外,开发者还可以创建自定义模块,用于组织和管理自己的代码。本文将详细介绍如何创…...
Python根据预设txt生成“你画我猜”题目PPT(素拓活动小工具)
Python根据预设txt生成“你画我猜”题目PPT(素拓活动小工具) 场景来源 去年单位内部的一次素拓活动,分工负责策划设置其中的“你画我猜”环节,网络上搜集到题目文字后,想着如何快速做成对应一页一页的PPT。第一时间想…...
小程序地理位置接口权限直接抄作业
小程序地理位置接口有什么功能? 随着小程序生态的发展,越来越多的小程序开发者会通过官方提供的自带接口来给用户提供便捷的服务。但是当涉及到地理位置接口时,却经常遇到申请驳回的问题,反复修改也无法通过,给的理由也…...
【Osek网络管理测试】[TG3_TC6]等待总线睡眠状态_2
🙋♂️ 【Osek网络管理测试】系列💁♂️点击跳转 文章目录 1.环境搭建2.测试目的3.测试步骤4.预期结果5.测试结果 1.环境搭建 硬件:VN1630 软件:CANoe 2.测试目的 验证DUT在满足进入等待睡眠状态的条件时是否进入该状态 …...
BEV下统一的多传感器融合框架 - FUTR3D
BEV下统一的多传感器融合框架 - FUTR3D 引言 在自动驾驶汽车或者移动机器人上,通常会配备许多种传感器,比如:光学相机、激光雷达、毫米波雷达等。由于不同传感器的数据形式不同,如RGB图像,点云等,不同模态…...
c#和python的flask接口的交互
一、灰度图像的传输 c#端的传输 //读入文件夹中的图像 Mat img2 new Mat(file, ImreadModes.AnyColor); //将图像的数据转换成和相机相同的buffer数据 byte[] image_buffer new byte[img2.Width * img2.Height]; int cn img2.Channels(); //通道数 if (cn 1){//将图像的数…...
Python测试框架Pytest的参数化详解
上篇博文介绍过,Pytest是目前比较成熟功能齐全的测试框架,使用率肯定也不断攀升。 在实际工作中,许多测试用例都是类似的重复,一个个写最后代码会显得很冗余。这里,我们来了解一下pytest.mark.parametrize装饰器&…...
KernelSU 如何不通过模块,直接修改系统分区
刚刚看了术哥发的视频,发现kernelSU通过挂载OverlayFS实现无需模块,即可直接修改系统分区,很是方便,并且安全性也很高,于是便有了这篇文章。 下面的教程与原视频存在差异,建议观看原视频后再结合本文章进行操作。 在未进行修改前,我们打开/system/文件夹,并在里面创建…...
红日靶场ATTCK 1通关攻略
环境 拓扑图 VM1 web服务器 win7(192.168.22.129,10.10.10.140) VM2 win2003(10.10.10.135) VM3 DC win2008(10.10.10.138) 环境搭建 win7: 设置内网两张网卡,开启…...
CellMarker | 人骨骼肌组织细胞Marker大全!~(强烈建议火速收藏!)
1写在前面 分享一下最近看到的2篇paper关于骨骼肌组织的细胞Marker,绝对的Atlas级好东西。👍 希望做单细胞的小伙伴觉得有用哦。😏 2常用marker(一) general_mrkrs <- c( MYH7, TNNT1, TNNT3, MYH1, MYH2, "C…...
游戏名台词大赏
文章目录 原神(圈内) 崩坏:星穹铁道(圈内) 崩坏3(圈内) 原神 只要不失去你的崇高,整个世界都会为你敞开。 总会有地上的生灵,敢于直面雷霆的威光。 谁也没有见过风&…...
OpenCV如何在图像中寻找轮廓(60)
返回:OpenCV系列文章目录(持续更新中......) 上一篇:OpenCV如何模板匹配(59) 下一篇 :OpenCV检测凸包(61) 目标 在本教程中,您将学习如何: 使用 OpenCV 函数 cv::findContours使用 OpenCV 函数 cv::d rawContours …...
进程和线程的概念是什么
进程和线程是操作系统中的两个核心概念,它们都与程序的执行有关,但在不同的层次上。 进程(Process) 定义:进程是正在运行的程序的实例。它包含了程序的代码、数据和程序执行时所需要的系统资源(如内存、文…...
小红书孕妇宝妈暴力拉新玩法,每日两小时,单日收益500+
哎呀,你好呀,亲爱的小伙伴们!我今天心血来潮,想和你们分享一个超级棒的方法,这个方法我亲自试过,超级有效!就是在小红书上针对孕妇和宝妈们进行引流的方法。听起来是不是很有趣呀?&a…...
【Spring】AOP中的核心概念:通知(Advice)和切点(Pointcut)
目录 1、通知(Advice) 1.1、前置通知 1.2、后置通知 1.3、返回通知 1.4、异常通知 1.5、通知的执行顺序 2、切点(Pointcut) 2.1、切点表达式的抽取 2.2、切点标识符 2.2.1、execution 2.2.2、within 2.2.3、annotation 1、通知(Advice) 通知(Advice):在…...
AIGC文生视频:Sora模型报告总结
作为世界模拟器的视频生成模型 我们探索视频数据生成模型的大规模训练。具体来说,我们在可变持续时间、分辨率和宽高比的视频和图像上联合训练文本条件扩散模型。我们利用对视频和图像潜在代码的时空补丁进行操作的变压器架构。我们最大的模型 Sora 能够生成一分钟…...
selenium发展史
Selenium Core 2004 年,Thoughtworks 的工程师 Jason Huggins 正在负责一个 Web 应用的测试工作,由于这个项目需要频繁回归,这导致他不得不每天做着重复且低效的工作。为了解决这个困境,Jason 开发了一个运行在 JavaScript 沙箱中…...
Python3:开发编码规范常用工具介绍
Python 赢得众人喜爱的重要原因有很多:简洁的语法、强大的标准库以及极低的上手成本,你既可以用它来写一些快糙猛的小脚本,同时也能用它来做一些真正的“大项目”,解决一些更为复杂的问题,总结下Python的主要特点有&am…...