Linux线程

1.线程概念

在一个程序里的一个执行路线就叫做线程(thread),更准确定义:线程是一个进程内部的控制序列

进程至少有一个执行路线,线程在进程内部运行,本质是在进程地址空间内运行,在Linux系统中,CPU眼中,看到的PCB都要比传统的进程更加轻量化,透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流。

例子

社会分配资源的基本实体是家庭,家庭内部有人员,父亲,母亲,孩子,爷爷和奶奶。每一个人都有自己的事情做,而家庭的每一人就是线程,家庭就是一个进程,社会就是操作系统分配资源。

 

线程的实现

在Linux内核中,线程的实现是通过共享同一个 mm_struct 来实现的。具体步骤如下:

  1. 创建任务结构(task_struct

    • 为每个线程创建一个 task_struct,每个 task_struct 包含线程的独立上下文信息,如栈、寄存器状态等。

  2. 共享内存管理结构(mm_struct

    • 所有线程共享同一个 mm_struct,这意味着它们共享同一个虚拟内存空间,包括代码段、数据段、堆和栈。

  3. 连接 task_structmm_struct

    • 每个 task_struct 通过 mm 指针指向共享的 mm_struct,从而实现线程之间的内存共享。

线程进行资源划分:本质是划分地址空间,获得一定合法虚拟地址,更深则是划分页表

线程进行资源共享:本质是对地址空间共享,更深是对页表条目的共享(物理地址空间)

分页式存储管理

虚拟地址和页表的由来

如果没有虚拟内存和分页机制,每一个用户程序在物理内存上所对应的空间必须是连续的。

 

 因为每一个程序的代码,数据长度都是不一样的,按照这样的映射方式,物理内存将会被分割成各种离散的,大小不同的块。运行一段时间后,有些程序会退出,那么它们占据的物理内存空间可以被回收,由于程序的运行和退出是随机的,释放出来的内存块大小和位置也各不相同,这就导致了物理内存被分割成许多离散的、大小不一的碎片,导致物理内存很多都是以碎片形式存在。

需要的是系统提供给用户的空间必须是连续的,但是物理内存最好不要连续。此时虚拟内存和分页便出现了。

把物理内存按照一个固定长度的页框进行分割,叫做物理页,每个页框包含一个物理页(page),一个页的大小等于页框的大小,大多数32位体现结构支持4KB的页,而64位的体系结构一般会支持8KB的页。

页框:一个存储区域

页:是一个数据块,可以存放在任何页框或磁盘中

有了这种机制,CPU便也不是直接访问物理内存空间,而是通过虚拟地址空间来间接访问物理内存地址。所谓的虚拟地址空间,是操作系统为每一个正在执行的进程分配一个逻辑地址,在32位机上,范围0~4G-1。

操作系统通过将虚拟地址和物理内存地址之间建立映射关系,也就是页表,这张表上记录了每一对页和页框的映射关系,能让CPU间接的访问物理内存地址。

把虚拟内存下的逻辑地址空间分为若干页,将物理内存空间分为若干页框,通过页表就能把连续的虚拟内存,映射到若干个不连续的物理内存页。就可以解决物理内存造成的碎片问题。

本质相同但用途不同

  • 本质相同:页和页框在本质上都是固定大小的内存块,它们的大小相同,都是内存管理的基本单位。

  • 用途不同

    • :属于虚拟地址空间,是程序逻辑上的内存划分,方便程序访问和管理。

    • 页框:属于物理地址空间,是实际物理内存的划分,用于存放逻辑地址空间中的页。

关于碎片

内存碎片化的类型

  • 外部碎片 :这是你描述的情况,即物理内存被分割成许多离散的、大小不同的空闲块,这些空闲块之间存在间隔,无法被合并成一个连续的大块内存。例如,一个程序需要分配 1MB 的连续内存,但内存中存在许多小于 1MB 的空闲块,这些空闲块加起来可能总大小超过了 1MB,但由于它们不是连续的,所以无法满足程序的分配请求,这些分散的空闲块就构成了外部碎片。

  • 内部碎片 :这是由于内存分配单位和程序实际需求之间的差异导致的。例如,在固定分区分配方式中,操作系统将物理内存划分成若干个固定大小的分区,每个分区分配给一个程序。如果程序的实际大小小于分区的大小,那么分区中剩余的部分就会产生内部碎片。比如,一个分区大小为 2MB,而程序只需要 1.5MB 的内存,那么剩下的 0.5MB 就是内部碎片。

物理内存不连续好处

 

. 物理内存最好不连续的原因

  • 内存分配的灵活性 :物理内存不连续可以提高内存分配的灵活性。计算机系统中运行的程序数量和大小是动态变化的,如果要求物理内存必须连续,那么在分配内存时会受到很大的限制。例如,当一个大程序请求一块很大的连续物理内存时,如果物理内存已经被其他程序分割成许多小块,那么就很难找到足够大的连续空闲块来满足请求。而物理内存不连续时,操作系统可以通过将多个不连续的物理内存块分配给一个程序,从而更好地利用有限的物理内存资源。

  • 减少内存碎片化的影响 :物理内存不连续可以有效减少外部碎片化的影响。如前面所述,内存碎片化会导致物理内存被分割成许多离散的、大小不同的空闲块,这些空闲块很难被有效地利用。而通过将不连续的物理内存块分配给程序,可以避免因为寻找连续空闲块而产生的碎片化问题。操作系统可以采用一些内存分配算法,如分页管理或分段管理,将物理内存划分为多个小块,然后根据程序的需求动态地分配这些小块,从而提高内存的利用率。

  • 支持虚拟内存技术 :现代计算机系统普遍采用虚拟内存技术,虚拟内存技术的核心是将逻辑地址空间和物理地址空间分离。物理内存不连续是虚拟内存技术的基础之一。虚拟内存技术通过在逻辑地址空间和物理地址空间之间建立映射关系,使得程序可以访问比实际物理内存更大的地址空间。操作系统可以根据需要将部分程序和数据从外存调入物理内存,或者将物理内存中暂时不用的部分程序和数据换出到外存。这种映射关系使得物理内存的分配和管理更加灵活,而不需要物理内存是连续的。例如,在分页管理方式下,逻辑地址空间被划分为多个固定大小的页面,物理地址空间被划分为多个固定大小的页框,操作系统通过页表将逻辑页面映射到物理页框,逻辑页面可以映射到不连续的物理页框,从而实现物理内存的不连续分配。

物理内存的管理

假设有一个可用的物理内存有4GB空间。按照一个页框的大小进行4kb进行划分,4gb空间就是4GB/4KB=1048576个页框。有这么多的物理页,操作系统就就要管理起来,操作系统需要知道那些页正在被使用,哪些页空闲等。

内核用struct page结构表示系统中的每个物理页,出于节省内存考虑,struct page中使用的大量的联合体union。

 

参数解释

flags:用来存放页的状态,这些状态是不是脏的,是不是被锁定在内存中等。flags每一位单独表示一种状态,所以它至少可以表示出32种不同的状态。 

这些标志定义在 <linux/page-flags.h>中。其中⼀些⽐特位⾮常重要,如PG_locked⽤于指定⻚是否锁定, PG_uptodate⽤于表⽰⻚的数据已经从块设备读取并且没有出现错误。

_mapcount:表示页表中有多少项指向该页,也就是这一页被引用了多少次。当计数值变化为-1的时候,就说明当前内核并没有引用这一项,于是在新的分配中就使用它。

virtual:是页的虚拟地址。通常情况下,它就是页在虚拟内存中的地址。有些内存(所谓的高端内存)并不永久的映射到内核地址空间上,

在内存管理的数据结构中,每个页结构(Page Structure)通常有一个 virtual 域,用于存储该页的虚拟地址。对于低内存,virtual 域会存储一个有效的虚拟地址,内核可以直接通过这个地址访问该页。对于高端内存,virtual 域为 NULL

struct page于物理页相关,而并非于虚拟页相关。而系统中的每一个物理页都要分配一个这样的结构体。

struct page_mem[1048576],每一个page都有一个下标,就可以知道每一个page起始地址,具体的物理地址=起始物理地址+页内(4KB)偏移,就可以不用在page里保存page起始地址了。

假设struct page占40个字节内存,假定系统的物理页为4KB大小,系统有4GB物理内存,那么系统中共有1048576个,所以描述这么多页面的page结构体消耗的内存只不过40MB,相对于4GB内存而言,是很小一部分。因此,管理系统中这么多物理页,代价是不大的。(windows系统页框大小为4KB)

详细计算过程

2.页表

页表中的每一个表项,指向一个物理页的开始地址。在32位系统中,虚拟内存的最大空间是4GB,

这是每一个用户程序都拥有的虚拟内存空间。要把4GB虚拟内存全部使用,那么页表中就需要能够表示所有的4GB空间,那么就需要4GB/4KB=1048576个表项。

虚拟内存看上去被虚线分割成一个个单元,其实并不是真的分割,虚拟内存仍然是连续的。这个虚线的单元仅仅表示它于页表中每一个表项的映射关系,可用映射到相同大小的一个物理内存页上。

页表中的物理地址,与物理内存之间,是随机映射的关系,那里可用就指向那里。虽然最终使用的物理内存是离散的,但是与虚拟内存对应的线性地址是连续的。处理器在访问数据,获取指令时,使用的是线性地址,只要它是连续的就行了,最终都能通过页表找到实际的物理地址。

在32位系统中,地址长度是4个字节,那么页表中的每一个表项就是占用四个字节,所以页表占据的总空间就是:1048576*4=4MB,也就是说映射表自己本身,就要占用4MB/4KB=1024个物理页。

 解决大容量页表的最好方法是:把页表看出普通文件,对它进行离散分离,即对页表再分页,由此形成多次页表的思想。

可以把单一页表拆分成1024个体积更小的映射表,这样,1024*1024,仍然可用覆盖4GB的物理内存。

这⾥的每⼀个表,就是真正的⻚表,所以⼀共有 1024 个⻚表。⼀个⻚表⾃⾝占⽤ 4KB ,那么
1024 个⻚表⼀共就占⽤了 4MB 的物理内存空间,和之前没差别啊?
从总数上看是这样的,但是一个应用程序是不可能完全使用全部的4GB空间的,也许只要几十个表就可以了。例如:一个用户的程序代码段,数据段,栈段,一共需要10MB的空间,那么使用3个页表就足够了。
计算过程:
每⼀个⻚表项指向⼀个 4KB 的物理⻚,那么⼀个⻚表中 1024 个⻚表项,⼀共能覆盖 4MB 的物理内
存;
那么 10MB 的程序,向上对⻬取整之后(4MB 的倍数,就是 12 MB),就需要 3 个⻚表就可以了。

页目录结构

每一个页框都被一个页表中的一个表项来指向了,那么1024个页表也需要被管理起来,管理页表的表称为页目录表,形成二级表。
所有页表的物理地址被页目录指向。页目录的物理地址被CR3指向,这个寄存器中,保存了当前正在执行任务的页目录地址。
所有操作系统在加载用户程序时,不仅仅需要为程序内容来分配物理内存,还需要用来保存程序的页目录和页表分配物理内存。
两级页表的地址转换
下⾯以⼀个逻辑地址为例。将逻辑地址( 0000000000,0000000001,11111111111 )转换为物
理地址的过程:

 

1. 在32位处理器中,采⽤4KB的⻚⼤⼩,则虚拟地址中低12位为⻚偏移,剩下⾼20位给⻚表,分成
两级,每个级别占10个bit(10+10)。
2. CR3 寄存器 读取⻚⽬录起始地址,再根据⼀级⻚号查⻚⽬录表,找到下⼀级⻚表在物理内存中
存放位置。
3. 根据⼆级⻚号查表,找到最终想要访问的内存块号。
4. 结合⻚内偏移量得到物理地址。
一个物理页的地址一定是4KB对齐的(最后12位全部为0),所以只需要记录物理页地址的高20位即可。上面是MMU的工作流程,MMU(Memory Manger Unit)是一种硬件电路,其速度很快,主要工作是进行内存管理,地址转换只是它承接的业务之一。
  • 4KB对齐的含义:如果一个地址是4KB对齐的,那么它的最后12位必须全部为0。这是因为4KB = 212字节,所以4KB对齐的地址在二进制表示中,最低12位必须为0。

  • 页框的起始地址:假设物理页框的大小为4KB,那么每个页框的起始地址必须是4KB的整数倍。例如,0x00000000、0x00001000、0x00002000等都是4KB对齐的地址。

为什么只需要记录物理页地址的高20位?

在一个32位的系统中,地址总共有32位。如果物理页框的大小为4KB,那么:

  • 低12位:用于表示页框内的偏移量(Offset)。因为每个页框有4KB = 212字节,所以低12位可以表示页框内的任意位置。

  • 高20位:用于表示页框的编号(Frame Number)。因为低12位已经用于偏移量,所以高20位用于表示物理页框的起始地址。

因此,对于4KB对齐的页框,只需要记录高20位即可唯一标识一个物理页框。

补充:
MMU要先进行两次页表查询确定物理地址,在确认权限问题后,MMU再将这个物理地址发送到总线,内存收到之后开始读取对应地址的数据并返回,那么当页表变成N级时,就变成了N次检索+1次读写,页表级数越多查询的步骤越多,对于CPU来说等待时间越长,效率越低。

单级页表对连续内存要求高,于是引进了多级页表,但是多级页表也有问题所在,虽然减少了连续存储的要求且减少存储空间的,但是降低了查询效率。于是增添了TLB来提高查询效率。

TLB的作用

为了缓解多级页表带来的性能问题,MMU使用TLB来缓存最近使用的页表项。TLB是一个高速缓存,存储了虚拟地址到物理地址的映射关系。通过TLB,可以快速完成地址转换,减少对页表的查询次数。

  • TLB命中率:如果TLB命中率较高,那么地址转换的延迟可以显著降低。

  • TLB未命中:如果TLB未命中,MMU需要访问页表,这会导致较大的延迟

 

缺页异常

CPU给MMU的虚拟地址,在TLB和页表都没有找到对应的物理页,就出现了缺页异常Page Fault,

它是由一个硬件中断触发的可用由软件逻辑纠正的错误。

假设目标内存页在物理内存中没有对应的物理页或者存在但无对应权限,CPU就无法获取数据,CPU就会报告一个缺页错误。

由于CPU没有数据就无法进行计算,CPU摆工了用户进程也就出现了缺页中断,进程会从用户态切换到内核态,并将缺页中断交给Page Fault Handler处理。

 

缺⻚中断会交给 PageFaultHandler 处理,其根据缺⻚中断的不同类型会进⾏不同的处理:
Hard Page Fault 也被称为 Major Page Fault ,翻译为硬缺⻚错误/主要缺⻚错误,这
时物理内存中没有对应的物理⻚,需要CPU打开磁盘设备读取到物理内存中,再让MMU建⽴虚拟
地址和物理地址的映射。
Soft Page Fault 也被称为 Minor Page Fault ,翻译为软缺⻚错误/次要缺⻚错误,这
时物理内存中是存在对应物理⻚的,只不过可能是其他进程调⼊的,发出缺⻚异常的进程不知道
⽽已,此时MMU只需要建⽴映射即可,⽆需从磁盘读取写⼊内存,⼀般出现在多进程共享内存区
域。
Invalid Page Fault 翻译为⽆效缺⻚错误,⽐如进程访问的内存地址越界访问,⼜⽐如对
空指针解引⽤内核就会报 segment fault 错误中断进程直接挂掉。

线程的优点

创建一个新线程的代价比要创建一个新进程小得多

与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少很多

        1.最主要的区别是线程的切换虚拟内存空间依然是相同的,但是进程切换是不同的。这两种上下文切换的处理都是通过操作系统内核来完成的,内核的这种切换过程伴随的最显著的性能损耗是将寄存器中的内容换出。

        2.还有一个隐藏损耗是上下文的切换会扰乱处理器的缓存机制。一旦切换上下文,处理器中的所有已经缓存的内存地址就没用了。还有一个区别是改变虚拟内存空间的时候,处理页表的TLB(块表)会被全部刷新,导致内存的访问在一段时间内相当的低效。但是在线程的切换不会有,还有硬件cache。

Cache是计算机系统中用于提高数据访问速度的重要组件。它通过存储频繁访问的数据和指令的副本,减少CPU访问主内存的次数,从而显著提高系统的性能。

 线程占用的资源要比进程少很多

能充分利用多处理器的可并行数量

在等待慢速I/O操作结束的同时,程序可执行其它的计算任务

计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现

I/O密集型应用,为了提高性能,将I/O操作重叠,线程可以同时等待不同的I/O操作

 多处理器系统

多处理器系统(Multiprocessor System)是指一个计算机系统中包含多个CPU(或核心)。这些CPU可以同时执行多个任务,从而提高系统的整体性能。多处理器系统可以是多核CPU(一个芯片上有多个核心)或多个CPU芯片的组合。

  • 多线程并行执行

    • 在多处理器系统中,操作系统可以将多个线程分配到不同的CPU核心上,从而实现并行执行。

    • 例如,一个进程包含多个线程,这些线程可以同时在不同的CPU核心上运行,充分利用多处理器的并行能力。

    • 这种并行执行可以显著提高程序的执行效率,尤其是在处理多任务或计算密集型任务时。

计算密集型应用

计算密集型应用(Compute-Intensive Application)是指那些主要消耗CPU资源进行计算的应用。这些应用通常涉及大量的数值计算、数据处理或复杂的算法,对CPU的计算能力要求较高。

 I/O密集型应用

I/O密集型应用(I/O-Intensive Application)是指那些主要消耗I/O资源进行数据输入和输出的应用。这些应用通常涉及大量的文件读写、网络通信等操作,对I/O性能要求较高。

线程缺点

1.创建太多线程会造成性能损失

2.健壮性降低(时间分配)

3.缺乏访问控制

线程异常

单个线程出现除零,野指针问题导致线程崩溃,进程也会随着崩溃

线程是进程的执行分支,线程出现异常,就类似进程出异常,进而触发信号进制,终止进程,进程终止,该进程内的所有线程也就随机退出。

Linux进程与线程

进程和线程

进程是资源分配的基本单位

线程是调递的基本单位

线程共享进程数据,但也有一部分自己的数据:

线程ID,一组寄存器,栈,errno,信号屏蔽字,调度优先级

进程的多个线程共享

同一地址空间,Text Segement,Data Segment都是共享的,如果定义一个函数,在各线程都能调用,定义一个全局变量,在各线程都可以访问到,还有一下资源是共享:

文件描述符表,每种信号的处理方式(SIG_ IGN、SIG_ DFL或者⾃定义的信号处理函数),当前工作目录,用户id和组id。

进程和线程关系图

 

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

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

相关文章

【TI MSPM0】GPIO学习

一、文件样例查找 以GPIO软件轮询为例 下面的四个文件夹分别为不同开发环境提供支持 二、工程导入 1.点击file-点击import project 2.点击browse 3.找到对应的文件打开&#xff0c;选择 推荐使用ticlang,能够提供更加优化的效率 点击finish 三、工程学习 1.readme 文件 &a…

二叉树的基本操作与实现:C语言深度剖析

目录 代码整体框架 1. #define _CRT_SECURE_NO_WARNINGS 2. 头文件引入 3. typedef int BTtype; 4. 二叉树节点结构体定义 二叉树的创建 1. BuyNode 函数 2. CreatNode 函数 二叉树的遍历 前序遍历 中序遍历 后序遍历 二叉树属性的计算 节点个…

深入解析 Latent Diffusion Model(潜在扩散模型,LDMs)(代码实现)

深入解析 Latent Diffusion Model&#xff1a;从传统 Diffusion Model 到高效图像生成的进化 近年来&#xff0c;生成模型在图像合成领域取得了显著进展&#xff0c;其中 Diffusion Model&#xff08;扩散模型&#xff0c;DMs&#xff09;以其出色的生成质量和理论上的稳健性逐…

线性回归原理推导与应用(五):波士顿房价预测实战

波士顿房价是一个非常经典的多元线性回归入门案例数据集。波士顿房价预测数据集包含了可能会影响房价的十三个因素&#xff0c;并给出了实际的房价&#xff08;单位为万美元&#xff09; 波士顿房价数据集数据集下载地址&#xff1a;https://www.kaggle.com/datasets/altavish…

基于CATIA二次开发的低音炮腔体容积精准计算技术详解

一、功能概述 本工具通过PySide6与CATIA V5深度集成&#xff0c;实现了低音炮上下腔体内体积的自动化测量系统。系统采用三维实体建模法进行容积计算&#xff0c;相较于传统手工计算方式&#xff0c;精度提升可达0.5%。主要功能模块包括&#xff1a; 壳体特征自动识别动态草图…

向量数据库原理及选型

向量数据库 什么是向量什么是向量数据库原理应用场景 向量数据库的选型主流向量数据库介绍向量数据库对比主流向量数据库对比表 选型建议 什么是向量 向量是一组有序的数值&#xff0c;表示在多维空间中的位置或方向。向量通常用一个列或行的数字集合来表示&#xff0c;这些数…

IE代理切换器v1.2免费版

虽然IE浏览器已经过时了&#xff0c;但很多其他浏览器&#xff0c;比如谷歌浏览器的代理服务器设置&#xff0c;都还是基于IE浏览器来进行设置的&#xff0c;如果你的工作场景需要切换不同的代理服务器来访问网络&#xff0c;那这款工具适合你&#xff0c;目前该工具可以实现IE…

模运算的艺术:从基础到高阶的算法竞赛应用

在算法竞赛中&#xff0c;模运算&#xff08;取模运算&#xff09;是一个非常重要的概念&#xff0c;尤其在处理大数、防止溢出、以及解决与周期性相关的问题时。C 中的模运算使用 % 运算符&#xff0c;但它的行为和使用场景需要特别注意。 1. 模运算的基本概念 模运算是指求一…

SpringBoot前后端不分离,前端如何解析后端返回html所携带的参数

有一个SpringBoot实现的前后端不分离项目&#xff0c;当前端跳转某个界面时&#xff0c;比如下面的菜单树按钮&#xff0c;后端在返回页面menuTree.html时&#xff0c;还携带了一个参数角色roleId&#xff0c;以便打开菜单树&#xff0c;还要根据这个角色查询对应的分配授权的菜…

操作系统八股文整理(一)

操作系统八股文整理 一、进程和线程的区别二、进程与线程的切换过程一、进程切换进程切换的步骤&#xff1a; 二、线程切换线程切换的步骤&#xff1a; 三、进程切换与线程切换的对比四、上下文切换的优化 三、系统调用一、系统调用的触发二、从用户空间切换到内核空间三、执行…

卷积神经网络(CNN)之 EfficientNet

在深度学习领域&#xff0c;模型的计算效率与性能之间的平衡一直是一个核心挑战。随着卷积神经网络&#xff08;CNN&#xff09;在图像分类、目标检测等任务中取得显著成果&#xff0c;模型的复杂度和计算需求也急剧增加。2019年&#xff0c;Google Research 提出的 EfficientN…

leetcode0031 下一个排列-medium

1 题目&#xff1a; 下一个排列 官方标定难度&#xff1a;中等 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如&#xff0c;arr [1,2,3] &#xff0c;以下这些都可以视作 arr 的排列&#xff1a;[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一…

Suno的对手Luno:AI音乐开发「上传参考音频 - 方式二:通过URL的方式」 —— 「Luno Api系列|AI音乐API」第12篇

导读 今天来看下Luno Api的上传参考音频 - 方式一&#xff1a;通过二进制流的方式。 参考文件&#xff0c;主要是用于在创作的过程中&#xff0c;希望AI参考这个音乐的曲风和声音来进行创作&#xff0c; 这一节看看如何直接使用url的方式进行实现。 申请和使用 「已经有API…

【开源+代码解读】Search-R1:基于强化学习的检索增强大语言模型框架3小时即可打造个人AI-search

大语言模型(LLMs)在处理复杂推理和实时信息检索时面临两大挑战:知识局限性(无法获取最新外部知识)和检索灵活性不足(传统方法依赖固定检索流程)。现有方法如检索增强生成(RAG)和工具调用(Tool-Use)存在以下问题: RAG:单轮检索导致上下文不足,无法适应多轮交互场景…

Blender-MCP服务源码2-依赖分析

Blender-MCP服务源码2-依赖分析 有个大佬做了一个Blender-MCP源码&#xff0c;第一次提交代码是【2025年3月7号】今天是【2025年月15日】也就是刚过去一周的时间&#xff0c;所以想从0开始学习这个代码&#xff0c;了解一下大佬们的开发思路 1-核心知识点 from mcp.server.fas…

【孟德尔随机化】Leave-one-out analysis的异常点,判断

下面Leave-one-out analysis的结果&#xff0c;第一条线代表去掉rs174564的结果&#xff0c;一些文献把这种情况判断为异常点/离群点&#xff0c;我们接下来看看其他结果 散点图的结果&#xff0c;最旁边的就是rs174564&#xff0c;这个SNP的点 在看下RadialMR的结果&#xff0…

【计算机网络】2物理层

物理层任务:实现相邻节点之间比特(或)的传输 1.通信基础 1.1.基本概念 1.1.1.信源,信宿,信道,数据,信号 数据通信系统主要划分为信源、信道、信宿三部分。 信源:产生和发送数据的源头。 信宿:接收数据的终点。 信道:信号的传输介质。 数据和信号都有模拟或数字…

kubernetes|云原生|部署单master的kubernetes 1.25.5版本集群完全记录(使用contained 运行时)

一、 部署目标&#xff1a; kubernetes版本1.19&#xff0c;1.23的前后差异还是比较巨大的&#xff0c;到1.25版本&#xff0c;为了追求高性能&#xff0c;自然还是需要使用containerd&#xff0c;本文将主要讲述在centos7虚拟机下部署kubernetes 1.25.5集群&#xff0c;使用…

DeepSeek+Dify本地部署私有化知识库

1.Windows安装docker Windows安装Docker-CSDN博客 2.安装olloma https://ollama.com/ 安装完成&#xff0c;可以在桌面右下角看到olloma图标 3.安装deepseekR1模型 ollama官网&#xff08;deepseek-r1&#xff09;&#xff0c;找到deepseek模型 选择合适大小的模型&#xff…

[Linux][经验总结]Ubuntu6.11.0 docker更换镜像源(实操可用的正确方法)

一、前言 关于Ubuntu更换docker镜像源&#xff0c;网上有很多的教程&#xff0c;但在实操中发现&#xff0c;更换的源无法生效——原因是我的docker是在系统安装时&#xff0c;选择附加安装的package的方式安装的。 现将处理过程记录如下。 二、获取镜像源 在网上随便找个几…