操作系统 4.3-生磁盘的使用

磁盘的物理组成

  1. 盘面

    • 磁盘由多个盘面组成,每个盘面上都有数据存储的区域。

  2. 磁道

    • 每个盘面上都有若干个同心圆,这些同心圆称为磁道。磁道是数据存储的路径。

  3. 扇区

    • 磁道被进一步划分为若干个扇区,扇区是磁盘的最小访问单位。

    • 扇区大小通常为512字节。

磁盘的io流程

该幻灯片描述了磁盘的输入/输出(I/O)过程,具体步骤如下:

  1. 开始使用磁盘

    • 首先,系统需要通过IDE控制器与磁盘建立连接,开始磁盘的I/O操作。

  2. 磁盘I/O过程

    • 磁盘的I/O过程包括以下几个步骤:控制器、寻道、旋转、传输。

  3. 寻道

    • 控制器发送指令,使磁头移动到正确的磁道上。这是为了定位到数据所在的物理位置。

  4. 旋转

    • 磁盘旋转,使得目标扇区移动到磁头下方。这个过程需要等待磁盘旋转到正确的位置,可能会有一定的延迟。

  5. 传输

    • 一旦目标扇区位于磁头下方,数据就可以从磁盘读取到内存中,或者从内存写入到磁盘中。

  6. 内存缓存

    • 读取或写入的数据首先会进入内存缓存。对于读取操作,数据从磁盘读出后存储在内存缓存中;对于写操作,数据首先写入内存缓存,然后再从缓存写入磁盘。

使用磁盘

柱面(Cylinder)

柱面是磁盘上所有盘面中具有相同径向位置的磁道的集合。

当计算机需要读取或写入数据时,它会根据柱面号、磁头号和扇区号来确定目标数据的位置。

通过控制磁头的移动和盘片的旋转,计算机可以准确地定位到特定柱面上的特定扇区,进行数据的读写操作。

磁头(Head)

每个盘面对应一个磁头

所有的磁头都是连在同一个磁臂上的,因此所有磁头只能“共进退”。

每个磁头上都有读和写的操作装置,用于读取和写入数据。

磁头臂是支持磁头的可移动臂,通过电动机或电磁力控制,可以使磁头在盘片上移动到不同的磁道位置。

扇区(Sector)

每个盘片被划分为一个个磁道,每个磁道又划分为一个个扇区。

扇区是磁盘的最小访问单位,通常为512字节。

在读取或写入数据时,磁头需要准确地定位到相应的扇区。磁盘驱动器在向磁盘读取和写入数据时,要以扇区为单位。

代码分析

从提供的幻灯片内容中,我们可以提取出两个函数的代码,它们是 do_hd_request hd_out。以下是提取的代码和总结:

提取的代码

void do_hd_request(void) {...hd_out(dev, nsect, sec, head, cyl, WIN_WRITE, ...); // 调用hd_out函数port_write(HD_DATA, CURRENT->buffer, 256); // 将数据写入硬盘
}
​
void hd_out(drive, nsect, sec, head, cyl, cmd...) {port = HD_DATA; // 数据寄存器端口(0x1f0)outb_p(nsect, ++port); // 输出扇区数outb_p(sec, ++port);   // 输出起始扇区号outb_p(cyl, ++port);   // 输出柱面号outb_p(cyl >> 8, ++port); // 输出柱面号的高字节outb_p(0xA0 | (drive << 4) | head, ++port); // 输出驱动器和磁头信息outb_p(cmd, ++port); // 输出命令
}

代码总结

  1. do_hd_request 函数

    • 这个函数处理硬盘的I/O请求。

    • 它调用 hd_out 函数来设置硬盘控制器的参数,包括设备号(dev)、扇区数(nsect)、扇区号(sec)、磁头号(head)、柱面号(cyl)等。

    • 然后,它使用 port_write 函数将数据从内存缓冲区(CURRENT->buffer)写入硬盘,这里写入的数据量为256字节。

  2. hd_out 函数

    • 这个函数负责将控制命令和参数输出到硬盘控制器。

    • 它首先设置数据寄存器端口(HD_DATA)。

    • 然后,它使用 outb_p 函数依次输出扇区数、扇区号、柱面号、柱面号的高字节、驱动器和磁头信息以及命令。

    • 这些参数用于控制硬盘的读写操作,例如移动磁头到指定的柱面和磁头位置,然后读取或写入指定的扇区。

这些代码是磁盘驱动程序的核心部分,它们实现了操作系统与硬盘硬件之间的直接交互,是文件系统和数据存储管理的基础。

如何通过盘块号读写磁盘

盘块

盘块(Block)是文件系统中用于数据存储和管理的一个逻辑概念,它是文件系统中数据存储的基本单位。盘块是逻辑上的划分,不同于磁盘物理结构中的扇区(Sector)、柱面(Cylinder)和磁头(Head)等概念。以下是盘块的详细解释:

  1. 盘块号

    • 每个盘块都有一个唯一的标识符,称为盘块号(Block Number)。盘块号用于在文件系统中定位和访问特定的盘块。

  2. 盘块与扇区的关系

    • 盘块通常由一个或多个扇区组成。一个扇区是磁盘上最小的物理存储单位,通常大小为512字节。

    • 文件系统将一个或多个连续的扇区组合成一个盘块,以提高数据管理的效率。

  3. 盘块的分配

    • 文件系统使用盘块分配表(Block Allocation Table, BAT)或inode(索引节点)等数据结构来记录每个文件占用的盘块信息。

    • 当文件被创建或修改时,文件系统会分配新的盘块或更新现有文件的盘块信息。

  4. 盘块的优缺点

    • 优点:简化了文件数据的管理,提高了数据存储和检索的效率。

    • 缺点:如果文件大小不是盘块大小的整数倍,最后一个盘块可能会有未使用的空间,导致一定的空间浪费。就是用空间换时间

为什么使用盘块

  1. 磁盘访问时间的组成

    • 磁盘访问时间包括写入控制器时间、寻道时间、旋转时间和传输时间。

    • 寻道时间:磁头移动到目标磁道的时间,通常在12毫秒到8毫秒之间。

    • 旋转时间:磁盘旋转到目标扇区的时间,对于7200转/分钟的硬盘,半周大约需要4毫秒。

    • 传输时间:数据从磁盘传输到内存的时间,大约0.3毫秒(50MB/秒)。

  2. 盘块相邻的优势

    • 相邻的盘块在物理位置上接近,因此可以快速连续读出,减少了寻道时间和旋转时间,提高了磁盘访问效率

优点分析

  • 提高效率:通过减少寻道时间和旋转时间,提高了磁盘访问的速度,从而提高了整体的系统性能。

  • 抽象层次:操作系统通过提供这一层抽象,隐藏了磁盘的物理访问细节,使得上层应用程序可以更加方便地使用磁盘资源。

如何编址?为什么这样编址?

  • 如何编址:磁盘驱动通过算法将盘块号映射到CHS地址。这通常涉及到磁盘的几何结构和盘块的布局。

  • 为什么这样编址:这种编址方式是为了优化磁盘访问效率。通过将相邻的盘块放在磁盘上的相邻位置,可以减少寻道时间和旋转时间,从而提高数据访问速度。

扇区号的获得

从CHS到扇区号

  • CHS地址转换:磁盘的物理地址通常由柱面号(Cylinder)、磁头号(Head)和扇区号(Sector)组成。幻灯片中提到的公式 Cx(HeadsxSectors) + HxSectors + S 用于计算从CHS地址到扇区号的转换。

    • C:柱面号

    • Heads:磁盘上的磁头数

    • Sectors:每个磁道上的扇区数

    • H:磁头号

    • S:扇区号

磁盘请求的创建和处理过程

从提供的幻灯片内容中,我们可以提取出两个函数的代码,它们是 make_request do_hd_request。以下是提取的代码和分析:

提取的代码

// 创建一个磁盘请求
static void make_request()
{struct request *req;req = request + NR_REQUEST;req->sector = bh->b_blocknr << 1;add_request(major + blk_dev, req);
}
​
// 处理硬盘请求
void do_hd_request(void)
{unsigned int block = CURRENT->sector;asm volatile ("divl %4, %%eax;"    // block / sect (每个磁头的扇区数)"=a" (block),        // 输入:eax = 被除数"=d" (sec),          // 输出:edx = 余数(扇区号)"0" (block),         // 输入:eax = 被除数"1" (0),             // 输入:edx = 0(初始化为0)"r" (hd_info[dev].sect) // 输入:ecx = 除数(每个磁头的扇区数));asm volatile ("divl %4, %%eax;"    // (block / sect) / head (磁头数)"=a" (cyl),          // 输出:eax = 商(柱面号)"=d" (head),         // 输出:edx = 余数(磁头号)"0" (block),         // 输入:eax = 被除数"1" (0),             // 输入:edx = 0(初始化为0)"r" (hd_info[dev].head) // 输入:ecx = 除数(磁头数));hd_out(dev, nsect, sec, head, cyl, WIN_WRITE, ...);...
}

代码分析

  1. make_request 函数

    • 这个函数用于创建一个新的磁盘请求

    • 它分配一个新的请求结构体 req,并设置请求的扇区号 req->sector

    • bh->b_blocknr << 1:将块号左移一位,为了将块号转换为扇区号(假设每个块由两个扇区组成)。

    • add_request:将新创建的请求添加到请求队列中。

  2. do_hd_request 函数

    • 这个函数处理硬盘请求,将盘块号转换为CHS地址,并调用 hd_out 函数执行实际的磁盘操作。

    • CURRENT->sector:获取当前请求的扇区号。

    • 使用内联汇编(asm volatile)进行除法运算,将扇区号转换为柱面号(cyl)、磁头号(head)和扇区号(sec)。

      • 第一个除法运算计算扇区号(sec)。

      • 第二个除法运算计算柱面号(cyl)和磁头号(head)。

    • hd_out:执行实际的磁盘操作,包括寻道、旋转和数据传输。

总结

这段代码展示了Linux 0.11内核中磁盘请求的创建和处理过程。make_request 函数负责创建新的磁盘请求,而 do_hd_request 函数负责将盘块号转换为CHS地址,并执行实际的磁盘操作。

通过内联汇编进行除法运算,实现了从盘块号到CHS地址的转换,这是磁盘驱动程序中的关键步骤。

多个进程使用磁盘

多进程通过队列使用磁盘

  1. 请求队列

    • 当多个进程需要访问磁盘时,它们的请求被放入一个请求队列中。这个队列管理所有磁盘访问请求,确保它们有序地被处理。

  2. 磁盘驱动

    • 磁盘驱动负责从请求队列中取出请求,并将其转换为磁盘控制器可以理解的CHS(柱面、磁头、扇区)地址。

  3. 磁盘控制器

    • 磁盘控制器根据磁盘驱动提供的CHS地址执行实际的磁盘操作,如寻道、旋转和数据传输。

磁盘调度

  1. 调度目标

    • 磁盘调度的主要目标是最小化平均访问延迟。这意味着调度算法需要尽可能减少磁盘访问请求的等待时间。

  2. 调度时主要考察的因素

    • 寻道时间:磁头移动到目标磁道的时间,这是磁盘访问时间中的主要部分。

    • 旋转时间:磁盘旋转到目标扇区的时间。

    • 传输时间:数据从磁盘传输到内存的时间。

  3. 调度算法

    • FCFS(First-Come, First-Served):最简单的调度算法,按照请求到达的顺序处理。虽然公平,但可能不是最高效的,因为它不考虑磁头的当前位置或请求的物理位置。

    • 更复杂的算法:如SSTF(Shortest Seek Time First)、SCAN(Elevator Algorithm)等,这些算法试图通过优化磁头移动路径来减少寻道时间,从而提高整体性能。

FCFS

  1. 最直观、最公平的调度

    • FCFS算法按照请求到达的顺序处理,确保每个请求都能被公平地处理。

  2. 实例分析

    • 磁头开始位置为53。

    • 请求队列为:98, 183, 37, 122, 14, 124, 65, 67。

  3. 磁头移动

    • FCFS算法导致磁头共移动了640个磁道。

    • 磁头在移动过程中处理了经过的请求。

  4. 磁头在长途奔袭

    • 图中显示了磁头在处理请求时的移动路径,磁头需要在磁盘上进行大量的移动,这可能导致效率低下。

  5. 效率问题

    • FCFS算法虽然公平,但可能导致磁头在磁盘上进行大量的寻道操作,增加了寻道时间和旋转时间,从而降低了磁盘的整体性能。

SSTF

SSTF(Shortest Seek Time First,最短寻道时间优先)磁盘调度算法。SSTF算法是一种优化磁盘访问时间的算法,它选择距离当前磁头位置最近的请求进行处理,以减少磁头移动的距离。以下是对幻灯片内容的分析:

  1. 算法原理

    • SSTF算法选择距离当前磁头位置最近的请求进行处理,以减少寻道时间。

    • 这种方法可以显著减少磁头移动的总距离,从而提高磁盘访问效率。

  2. 实例分析

    • 磁头开始位置为53。

    • 请求队列为:98, 183, 37, 122, 14, 124, 65, 67。

  3. 磁头移动

    • 在这个实例中,SSTF算法导致磁头共移动了236个磁道(4+53+169)。

    • 相比FCFS算法的640个磁道,SSTF算法显著减少了磁头移动的距离。

  4. 效率提升

    • 通过优先处理距离当前磁头位置最近的请求,SSTF算法可以更快地响应请求,减少等待时间。

  5. 饥饿问题

    • SSTF算法存在饥饿问题,即远离当前磁头位置的请求可能会长时间得不到处理。

    • 如果在处理183号请求之前,又来了一些中间磁道的请求,那么183号请求可能会被推迟处理,导致延迟。

SCAN

SCAN磁盘调度算法,也称为电梯算法,它是一种常见的磁盘调度策略,旨在优化磁盘的寻道操作,减少寻道时间。

  1. 算法原理

    • SCAN算法模拟电梯的运行方式,磁头从一个方向开始移动,直到达到最后一个请求,然后改变方向,继续处理另一方向的请求。

    • 这种算法确保每个请求最终都会被处理,避免了SSTF算法中可能出现的饥饿问题。

  2. 实例分析

    • 磁头开始位置为53。

    • 请求队列为:98, 183, 37, 122, 14, 124, 65, 67。

  3. 磁头移动

    • 在这个实例中,SCAN算法导致磁头共移动了236个磁道(53+183)。

    • 与SSTF算法相比,SCAN算法在处理请求时更加公平,因为它确保了磁头会遍历所有请求。

  4. 公平性

    • SCAN算法通过确保每个方向上的请求都被处理,提高了算法的公平性。

  5. 效率

    • SCAN算法通过减少磁头的来回移动,提高了磁盘访问的效率。

    • 与SSTF相比,SCAN算法在处理大量随机分布的请求时,通常能提供更好的性能。

C-SCAN

这张幻灯片介绍了C-SCAN(Circular SCAN)磁盘调度算法,这是一种类似于电梯算法的磁盘调度策略,但在到达一端后直接移动到另一端,而不是改变方向。以下是对幻灯片内容的分析和总结:

  1. 算法原理

    • C-SCAN算法从磁头的当前位置开始,向一个方向移动,处理所有请求,到达磁盘的一端后,直接移动到另一端,然后继续处理请求。

    • 这种算法确保了两端的请求都能被快速处理。

  2. 实例分析

    • 磁头开始位置为53。

    • 请求队列为:98, 183, 37, 122, 14, 124, 65, 67。

  3. 磁头移动

    • 在这个实例中,C-SCAN算法导致磁头共移动了157+200个磁道。

    • 其中200个磁道是磁头从一端移动到另一端的距离,这个过程很快,因为它是连续的,没有寻道时间。

  4. 效率

    • C-SCAN算法通过直接从一端移动到另一端,减少了磁头的寻道时间,提高了磁盘访问的效率。

    • 这种算法特别适合于请求分布均匀的情况,因为它可以确保所有请求都能被快速处理。

  5. 公平性

    • C-SCAN算法在处理请求时,可能会对靠近磁头起始位置的请求提供更快的服务,而对远离起始位置的请求提供较慢的服务。

代码实现

从提供的幻灯片内容中,我们可以提取出两个函数的代码:make_request add_request,以及一个宏定义 IN_ORDER。以下是提取的代码和总结:

提取的代码

// 创建一个磁盘请求
static void make_request()
{struct request *req;req->sector = bh->b_blocknr << 1;add_request(major + blk_dev, req);
}
​
// 将请求添加到请求队列
static void add_request(struct blk_dev_struct *dev, struct request *req)
{struct request *tmp = dev->current_request;req->next = NULL;cli(); // 关中断(互斥)for (; tmp->next; tmp = tmp->next)if (IN_ORDER(tmp, req) || !IN_ORDER(tmp, tmp->next))&& IN_ORDER(req, tmp->next)) break;req->next = tmp->next; tmp->next = req; sti();
}
​
// 判断请求是否有序
#define IN_ORDER(s1, s2) \((s1)->dev < (s2)->dev || \((s1)->dev == (s2)->dev && (s1)->sector < (s2)->sector))

代码总结

  1. make_request 函数

    • 这个函数初始化一个新的磁盘请求,设置请求的扇区号 req->sector,并将请求添加到磁盘请求队列中。

    • bh->b_blocknr << 1:假设每个块由两个扇区组成,因此将块号左移一位来计算扇区号。

  2. add_request 函数

    • 这个函数将一个新的请求插入到磁盘请求队列中,保持队列的有序性。

    • 使用 cli() 关闭中断来确保在操作请求队列时的互斥访问。

    • 通过 IN_ORDER 宏判断请求是否有序,如果新请求应该插入到 tmptmp->next 之间,则进行插入。

    • 使用 sti() 重新开启中断。

  3. IN_ORDER

    • 这个宏用于判断两个请求是否有序,即是否按照设备号和扇区号的顺序排列。

    • 如果第一个请求的设备号小于第二个请求的设备号,或者设备号相同但扇区号小于第二个请求的扇区号,则认为有序。

总结如何使用生磁盘

这张幻灯片介绍了操作系统中生磁盘(raw disk)的使用流程,以及如何通过磁盘驱动程序来管理多个进程对磁盘的访问。

  1. 进程获取盘块号

    • 进程首先需要获取到要访问的盘块号(block number)。

  2. 计算扇区号

    • 根据盘块号计算出对应的扇区号(sector number)。这通常涉及到将盘块号映射到磁盘的物理地址。

  3. 创建请求并加入请求队列

    • 使用计算出的扇区号创建一个磁盘请求(make req)。

    • 将该请求加入到请求队列中(add_request),可能使用电梯算法(SCAN算法)来优化请求的处理顺序。

  4. 进程等待

    • 进程在发起磁盘请求后进入等待状态(sleep_on)。

  5. 磁盘中断处理

    • 当磁盘操作完成时,磁盘控制器会产生一个中断信号。

    • 中断处理程序(read_intr)被触发,唤醒等待的进程。

  6. 执行磁盘请求

    • 磁盘驱动程序处理请求(do_hd_request),计算出具体的柱面(cylinder)、磁头(head)和扇区号(sector)。

  7. 端口写入

    • 使用端口写入操作(hd_out),通过outp函数将数据写入磁盘控制器的端口,完成数据的实际读写操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/76334.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PT抽ETM如何包含power信息

在primetime中&#xff0c;可以使用extract_model -power指令使ETM包含power的信息。需要注意的是&#xff0c;需要先设置set power_enable_analysis为true。 例如得到有power信息的ETM指令如下&#xff08;示例&#xff09;&#xff1a; set power_enable_analysis true ex…

Linux服务器网卡深度解析:从ifconfig输出到生产环境性能调优实战

Linux服务器网卡深度解析&#xff1a;从ifconfig输出到生产环境性能调优实战 Linux服务器网卡深度解析&#xff1a;从ifconfig输出到生产环境性能调优实战一、背景二、生产环境的服务器部署情况三、拆解一个真实的 ifconfig 输出1、先看 MAC 地址2、再看设备的 interrupt 和 me…

996引擎-源码学习:PureMVC Lua 中的 Facade 类

996引擎-源码学习:PureMVC Lua 中的 Facade 类 1. 核心概念1.1 外观模式1.2 多例模式2. 关键组件NotificationController:ModelView3. 主要功能4. 初始化流程5. 通信机制6. 生命周期管理1. Facade 初始化流程图2. 发送通知时序图中介者 PlayerBestRingLayerMediatorOpenLayer …

链式多分支规则树模型的应用

目录 开始调用 初始化 欢迎关注我的博客&#xff01;26届java选手&#xff0c;一起加油&#x1f498;&#x1f4a6;&#x1f468;‍&#x1f393;&#x1f604;&#x1f602; 引入 最近在学习一个项目中的链式多分枝规则树模型的使用&#xff0c;模型如下&#xff1a; 如图所…

GitLab之搭建(Building GitLab)

GitLab之搭建 “ 在企业开发过程中&#xff0c;GitLab凭借其强大的版本管理、CI/CD集成和项目管理功能&#xff0c;成为许多团队的首选工具。本文将探讨GitLab的基础介绍、搭建过程、权限管理、代码审查以及团队知识管理等方面。通过详细的步骤和实用的技巧&#xff0c;旨在帮…

蓝桥杯 小蓝的操作(一维差分)

问题描述 一个数组 aa 中共包含 nn 个数&#xff0c;问最少多少次操作&#xff0c;可以让 aa 数组所有数都变成 11 。 操作的内容是&#xff1a;每次操作可以任选一个区间使得区间内的所有数字减 11 。 数据保证一定有解。 输入格式 第一行一个整数 nn 表示有 nn 个整数。 …

C# net CMS相关开源软件 技术选型 可行性分析

C# net CMS相关开源软件 技术选型 可行性分析 OrchardCMS(微软主导) https://github.com/OrchardCMS/OrchardCore https://docs.orchardcore.net/en/latest/ BSD Umbraco-CMS&#xff08;丹麦&#xff09; https://github.com/umbraco/Umbraco-CMS https://docs.umbraco.com/…

程序化广告行业(77/89):融资、并购与上市全景洞察

程序化广告行业&#xff08;77/89&#xff09;&#xff1a;融资、并购与上市全景洞察 大家好呀&#xff01;一直以来&#xff0c;我都希望能和大家一起在技术知识的海洋里畅游、学习进步。前面我们已经了解了程序化广告行业的发展态势、PC端和移动端投放差异以及行业融资的大致…

【解决方法】VMware 此平台不支持虚拟化Intel VT-x/EPT

目录 1. 引言2. 问题描述3. 解决方法3.1 方法一&#xff08;临时&#xff09;3.2 方法二&#xff08;此方法非常离谱&#xff0c;永久有效&#xff09; 4. &#x1f911;鼓励一下5. 求关注6. 我的其他文章推荐 1. 引言 收集同学们遇到的各种VMware安装、使用过程中遇到的问题&a…

项目学习总结001

1. 策略模式和工厂模式 https://mp.weixin.qq.com/s/RG-h7r69JyKUlBZylJJIFQ 在软件开发中也常常遇到类似的情况&#xff0c;实现某一个功能有多个途径&#xff0c;此时可以使用一种设计模式来使得系统可以灵活地选择解决途径&#xff0c;也能够方便地增加新的解决途径。这就是…

OpenHarmony 5.0版本视频硬件编解码适配

一、简介 Codec HDI&#xff08;Hardware Device Interface&#xff09;对上层媒体服务提供视频编解码的驱动能力接口&#xff0c;主要功能有获取组件编解码能力&#xff0c;创建、销毁编解码器对象&#xff0c;启停编解码器操作&#xff0c;编解码处理等。 Codec HDI 2.0接口…

深度解析基于 Web Search MCP的Deep Research 实现逻辑

写在前面 大型语言模型(LLM)已成为我们获取信息、生成内容的重要工具。但它们的知识大多截止于训练数据的时间点,对于需要实时信息、跨领域知识整合、多角度观点比较的深度研究 (Deep Research) 任务,它们往往力有不逮。如何让 LLM 突破自身知识的局限,像人类研究员一样,…

鸿蒙案例---生肖抽卡

案例源码&#xff1a; Zodiac_cards: 鸿蒙生肖抽奖卡片 效果演示 初始布局 1. Badge 角标组件 此处为语雀内容卡片&#xff0c;点击链接查看&#xff1a;https://www.yuque.com/kevin-nzthp/lvl039/rccg0o4pkp3v6nua 2. Grid 布局 // 定义接口 interface ImageCount {url:…

基于RV1126开发板实现自学习图像分类方案

1. 方案简介 自学习&#xff1a;在识别前对物体图片进行模型学习&#xff0c;训练完成后通过算法分类得出图像的模型ID。 方案设计逻辑流程图&#xff0c;方案代码分为分为两个业务流程&#xff0c;主体代码负责抓取、合成图像&#xff0c;算法代码负责训练和检测功能。 2. 快速…

cat命令查看文件行数

在Linux和Unix-like操作系统中&#xff0c;cat命令主要用于查看文件内容&#xff0c;而不是直接用来查看文件行数。如果你想要查看一个文件的行数&#xff0c;可以使用以下几种方法&#xff1a; 方法1&#xff1a;使用wc命令 wc&#xff08;word count&#xff09;命令可以用…

git清理已经删除的远程分支

目录 命令作用 使用场景 示例流程 注意事项 常见问题 git remote update origin --prune git remote update origin --prune 是一个 Git 命令&#xff0c;用于 更新本地远程跟踪分支 并 清理&#xff08;删除&#xff09;本地已失效的远程分支引用。以下是详细分解&#…

NLP高频面试题(四十)——什么是 BitFit?

BitFit(Bias-term Fine-tuning)是一种参数高效的微调方法,专注于在预训练模型中仅调整偏置项(bias term),而将其他参数保持不变。这种方法在自然语言处理领域,尤其是在中小规模数据集上,展现出了与全量微调相媲美的性能,同时显著减少了计算资源的消耗。 什么是 BitFi…

Java-servlet(完结篇)过滤器乱码解决与监听器

Java-servlet&#xff08;完结篇&#xff09;过滤器乱码解决与监听器 前言一、过滤器乱码解决二、监听器1. HttpSessionListener2. ServletContextListener3. ServletRequestListener 三、监听器的使用场景Java-servlet 结语 前言 在之前的 Java Servlet 学习中&#xff0c;我…

为了避免unboundLocalError和为什么X的值一直不变呢?

## 1.为了避免unboundLocalError 发生unboundLocalError&#xff01; def generate_integer(level):if level 1:X randint(1,9)return X这里出错的原因在于&#xff0c;一旦if 后面的条件没有成立&#xff0c;然后X根本没出生&#xff0c;然后你去使用它&#xff0c;这是有…

opencv-python基础

一.opencv-python简述 其使用Numpy&#xff0c;所有OpenCV数组结构都转换为Numpy数组&#xff0c;是一个高度优化的数据库操作库。 二.环境安装 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python 三.基本概念 - 像素是图像的基本单元&#xff0c;每个…