- 博客(87)
- 收藏
- 关注
原创 进程间通信组件实现
AIO(Asynchronous I/O)和NIO(Non-blocking I/O)是两种高性能I/O模型,主要用于解决高并发场景下的I/O效率问题。数据流通道,允许相关进程(通常有父子关系)进行通信。在 Linux 内核中,设备模块是驱动硬件的核心组件,它们通过标准化的接口与内核交互。管道(Pipe)是 Linux 中最经典的进程间通信(IPC)机制之一,它提供了一种。因为大量网络IO,使用AIO的话会有大量的内核->用户空间的调用,命名管道,可用于任意进程间通信。,实现一个进程间通信组件。
2025-07-21 05:27:24
620
原创 用户态文件系统fuse
FUSE(Filesystem in Userspace)是一种让非特权用户在用户空间实现文件系统的机制。文件系统的逻辑实现不在内核态运行,而是在用户态运行,通过与内核中的 FUSE 模块通信实现文件操作的响应。
2025-07-03 09:07:31
844
原创 调度器之任务分组
我们先看以下两种场景。(1)执行(选项表示同时执行 10 条命令),编译 Linux 内核,同时运行视频播放器,如果给每个进程平均分配 CPU 时间,会导致视频播放很卡。(2)用户 1 启动 100 个进程,用户 2 启动 1 个进程,如果给每个进程平均分配 CPU 时 间,用户 2 的进程只能得到不到 1%的 CPU 时间,用户 2 的体验很差。怎么解决呢?把进程分组。
2025-07-03 09:06:22
830
原创 进程生命周期
Linux是多任务操作系统,系统中的每个进程能够分时复用CPU时间片,通过有效的进程调度策略实现多任务并行执行。进程在被CPU调度运行,等待CPU资源分配以及等待外部事件时会处于不同的状态。
2025-05-30 09:43:14
402
原创 内核进程基础
操作系统作为硬件的使用层,提供使用硬件资源的能力;进程作为操作系统的使用层,提供使用操作系统抽象出的资源层的能力。进程:是指计算机中已运行的程序。进程本身不是基本的运行单位,而是线程的容器。程序是指令、数据及其组织形式的描述,进程才是程序(指令和数据)的真正运行实例。Linux内核把进程叫做(任务),进程的虚拟地址空间可分为和,所有进程内核虚拟地址空间(内核页表全局唯一),每个进程有的用户虚拟地址空间。进程有两种特殊的形式:没有用户虚拟地址空间的进程叫;共享用户虚拟地址空间的进程叫。
2025-05-30 09:42:30
306
原创 RCU(Read-Copy Update)
为什么需要RCU?在Linux内核中,虽然已经有多种互斥机制(如、原子操作、等),但这些机制在某些场景下可能会成为性能瓶颈。是一种特殊的同步机制,主要用于解决读多写少的场景下的性能问题。RCU对于读多写少场景,性能比等都要高。它的设计目标是最大限度地减少读操作的开销,同时保证数据的一致性。为什么需要RCU?传统互斥机制的问题锁的开销:传统的锁机制(如)在读写冲突时会导致性能下降,尤其是在读多写少的场景中。读操作需要加锁,即使没有写操作,也会引入额外的开销。
2025-05-30 09:37:20
939
原创 内存屏障技术
程序在执行时,指令一般不按照源程序顺序执行,原因是为提高程序执行性能,会对它进行优化,主要为两种:编译器优化和CPU执行优化,可能会导致内存访问乱序。内存屏障(Memory Barrier)是一种保证内存访问顺序的方法,用来解决下面这些内存访问乱序问题。1)编译器编译代码时可能汇编指令,使编译出来的程序在处理器上运行更快,但是有时候优化的结果可能不符合程序员的意图,导致程序运行过程中出现问题。2)现代的处理器采用(每个流水线阶段能同时执行多条指令)和,能够在一个时钟周期并行执行多条指令。
2025-05-30 09:34:27
429
原创 每处理器变量和每处理器计数器
void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch) // batch即阈值s64 count;// 禁止内核抢占// 读取当前CPU的计数器值并计算新值if (count >= batch || count <= -batch) { // 当前CPU计数值超过阈值的情况// 将当前CPU的累计值加到全局count// 重置当前CPU的计数值} else {参考资料。
2025-05-30 09:33:08
600
原创 内核抢占、进程和中断互斥
内核抢占是指当进程在内核模式下运行的时候可以被其他进程抢占,编译内核时打开配置宏则允许内核抢占。抢占是指当进程在内核模式下运行的时候可以被其他进程抢占,如果优先级更高的进程处于就绪状态,强行剥夺当前进程的处理器使用权。
2025-05-30 09:27:57
267
原创 内核读写锁
内核自旋锁spinlock_t的一个不足就是没有区分读者和写着,即使多个读者之间也会进行竞争。内核实际是,从自旋锁衍生而来,是对自旋锁的改进,区分读者和写者,允许多个读者同时进入临界区,读者和写者互斥,写者和写者互斥。如果读者占有读锁,写者申请写锁的时候自旋等待。如果写者占有写锁,读者申请读锁的时候自旋等待。
2025-03-31 16:49:06
339
原创 内核自旋锁
自旋锁用于处理器之间的互斥,适合保护很短的临界区,并且。申请自旋锁的时候,如果自旋锁被其他处理器占有,本处理器(也称为内核的自旋锁是(queuedspinlock,也称为"FIFO ticket spinlock",票号锁),算法类似于银行柜台的排队叫号。(1)锁拥有,服务号是当前占有锁的进程的排队号。(2)每个进程申请锁的时候,首先申请一个排队号,然后轮询锁的服务号是否等于自己的排队号,如果等于,表示自己占有锁,可以进入临界区,否则继续轮询。
2025-03-31 16:48:20
292
原创 内核原子变量
原子变量用来实现对整数的互斥访问,通常用来实现。例如,我们写一行代码把变量a加1,编译器会把代码编译成3条汇编指令。(1)把变量a从内存加载到寄存器。(2)把寄存器的值加1。(3)把寄存器的值写回内存。在单处理器系统中,如果进程1和进程2都执行把变量a加1的操作,可能出现下面的执行顺序:预期结果是进程1和进程2执行完以后变量a的值加,但是因为在进程1把变量a的新值写回内存之前,进程调度器调度进程2,进程2从内存读取变量a的旧值,导致进程1和进程2执行完以后变量a的值实际只增加了1。
2025-03-31 16:46:54
267
原创 内核实时互斥量
内核mutex存在优先级反转的问题。什么是优先级反转?考虑一种情况,系统上有两个进程运行:进程A优先级高,进程C优先级低。假定进程C已经获取了一个互斥量,正在所保护的临界区中运行,且在短时间内不打算退出。但在进程C进入临界区之后不久,进程A也试图获取该互斥量。由于进程C已经获取到该互斥量,因而进程A必须等待。这导致高优先级的进程A等待低优先级的进程C。如果有第3个进程B,优先级介于进程A和进程C之间,情况会更加糟糕。假定进程C仍然持有锁,进程A在等待。现在进程B开始运行。
2025-03-31 16:46:11
394
原创 内核读写信号量
内核中的读写信号量提供了一个高效的同步机制,允许多个读者同时访问共享资源,但写者需要独占访问。用户空间中的读写锁提供了类似的功能,通过POSIX线程库可以实现读写锁,用于同步多线程访问共享资源。
2025-03-31 16:36:37
341
原创 内核信号量
信号量(Semaphore)是一种用于同步和互斥的机制,能够控制对共享资源的访问,广泛应用于多线程和多进程编程中。应用程序中使用的信号量是基于内核信号量实现的。
2025-03-31 16:32:14
368
原创 内核定时器2-高分辨率定时器
高分辨率定时器与低分辨率定时器相比,有如下两个根本性的不同。(1) 高分辨率定时器使用对定时器进行管理。(2) 定时器独立于周期时钟。即,精度可以达到纳秒级别。内核2.6.16版本开始,支持高分辨率定时器。在该版本中,低分辨率定时器的经典实现的基础部分已经替换为新的实现,该实现。由于低分辨率定时器的实现基于高分辨率机制,即使不启用高分辨率定时器,内核中也会联编(一部分)对高分辨率定时器的支持。当然,这种情况下系统只能够提供低分辨率定时功能。
2025-02-03 17:26:30
547
原创 内核定时器1-普通定时器
jiffies是内核中用于表示时间的一个全局变量,通常用于衡量系统自启动以来的时间流逝。它的作用类似于一个时钟计数器,在每个时钟中断时递增。具体来说,jiffies 用于表示经过的“滴答数”,每一滴答对应一个固定的时间间隔。jiffies是一个全局变量,类型通常为,它记录的是自系统启动以来的时钟滴答数。每个硬件时钟中断(或称为时钟滴答)都会增加jiffies的值。内核定时器、调度等功能依赖于jiffies来计算时间。jiffies定义代码如下。对于 64 位系统,jiffies_64。
2025-02-03 17:24:20
1338
原创 软中断介绍
软中断(Soft Interrupt)是一种由操作系统设计并执行的软件机制,它不是由硬件直接触发,而是由软件显式调用或触发的一种中断类型。软中断主要用于处理延迟执行的任务或轻量级异步任务,以减少对实时性的影响。因为它们的运作方式与上文描述的中断类似,但完全是用软件实现的,所以称为软中断(software interrupt)或softIRQ。通常软中断的优先级低于硬件中断,但高于普通进程调度。
2025-01-11 06:53:56
1369
1
原创 开启_禁止中断
软件可以禁止中断,,但是不可屏蔽中断(NMI,Non Maskable Interrupt)例外。禁止中断在需要临界区保护的场景下非常重要,避免中断打断正在执行的代码。禁止中断的接口如下。(2)local_irq_save(flags):首先把中断状态保存在参数flags中,然后禁止中断。这两个接口只能,不能禁止其他处理器的中断。禁止中断以后,处理器不再响应中断请求。开启中断的接口如下。(2)local irq_restore(flags):恢复本处理器的中断状态。
2025-01-11 06:53:04
842
原创 处理器间中断
处理器间中断(Inter-Processor Interrupt)是一种特殊的中断,在多处理器系统中,一 个处理器可以向其他处理器发送中断。要求目标处理器执行某件事情。处理器间中断是多核系统中用于处理核间通信的一种重要机制。
2025-01-11 06:52:05
734
1
原创 中断处理流程
对于中断控制器的每个中断源,向中断域添加硬件中断号到Linux中断号的映射时,内核分配一个Linux中断号和一个中断描述符irq_desc。
2024-12-23 06:11:03
875
原创 中断控制器及中断域
不同种类的中断控制器的访问方法存在差异,为了屏蔽差异,内核定义了中断控制器描述符irq_chip,每种中断控制器自定义各种操作函数。
2024-12-23 06:09:52
1108
原创 设备与文件系统关联
除极少数例外,设备文件都是由标准函数处理,类似于普通文件;设备文件也是通过虚拟文件系统(VFS)管理;普通文件和设备文件都是通过完全相同的接口访问;
2024-12-11 05:46:43
431
原创 字符设备操作
字符设备由;同时,内核维护了一个数据库,包括所有活动的cdev的示例;owneropsdevcount最初,字符设备的文件操作(ops)只包含用于打开相关设备文件(open方法;在使用驱动程序时,这总是第一个操作)的一个方法;因此,我们首先介绍该方法;
2024-12-11 05:41:19
317
原创 反碎片技术
内存碎片分为内部碎片和外部碎片:内部碎片指内存页里面的碎片;外部碎片指空闲的内存也是分散的,很难找到一组物理页连续的空闲内存页,无法满足超过一页的内存分配请求;内核有时需要分配超过一页的物理内存,因为内核使用线性映射区的虚拟地址,需要分配连续的物理页;使用巨型页,也需要分配连续的物理页;为可决外部碎片问题,内核引入反碎片技术:1)虚拟可移动区域;2)内存碎片整理;虚拟可移动区域是预防外部碎片的技术;内存碎片整理是在出现外部碎片以后消除外部碎片的技术;
2024-04-26 10:37:32
495
原创 巨型页原理
当运行内存需求量较大的应用程序时,如果使用长度位4KB的页,将会产生较多的TLB未命中和缺页异常,严重影响应用程序的性能;如果使用长度为2MB甚至更大的巨型页,可以大幅减少TLB未命中和缺页异常的数量,大幅提高应用程序的性能;这正是引入巨型页(Huge Page)的直接原因;巨型页首先需要处理器能够支持,然后需要内核支持;
2024-04-12 15:41:31
513
原创 页回收机制
申请分配物理页的时候,页分配器首先尝试使用低水线分配页;如果使用低水线分配失败,说明内存轻微不足,页分配器将会唤醒内存节点的页回收内核线程,异步回收页,然后尝试使用最低水线分配页;如果使用最低水线分配失败,说明内存严重不足,;针对不同的物理页,采用不同的回收策略;物理页根据是否有存储设备支持分为两类:1)可以被交换的页:没有存储设备支持的物理页,包括匿名页,以及tmpfs文件系统(内存中的文件系统)的文件页和进程在修改私有的文件映射时复制生成的匿名页;2)存储设备支持的文件页;
2024-04-12 15:37:28
448
原创 页表缓存TLB原理
处理器的内存管理单元(Memory Management Uint,MMU)负责把虚拟地址转换成物理地址,为了加快虚拟地址到物理地址的转换速度,避免每次转换都需要查询内存中的页表,处理器厂商在MMU中增加了一个高速缓存TLB(Translation Lookaside Buffer),TLB直译为转换后背缓冲区,也叫页表缓存;页表缓存用来缓存最近使用过的页表项,有些处理器使用两级页表缓存:第一级TLB分为指令TLB和数据TLB,取指令和取数据可以并行执行;
2024-04-12 15:35:58
1015
原创 用户空间缺页异常
当没有创建一个虚拟地址到物理地址的映射,或者创建了这样的映射,但是该物理页不可写的时候,MMU将会通过CPU产生一个缺页异常;handle_pte_fault的详细流程,do_anonymous_page,do_fault以及写时复制等,比较复杂,后续进行补充;1)启动程序的时候,内核为程序的代码段和数据段创建私有的文件映射,映射到进程的虚拟地址空间,第一次访问的时候触发文件页的缺页异常;2)进程使用mmap创建文件映射,把文件的一个区间映射到进程的虚拟地址空间,第一次访问的时候触发文件的缺页异常;
2024-04-12 15:35:01
458
原创 页表基本原理
前面四级页表的表项存放下一级页表的起始地址,直接页表的表项存放页帧号(Page Frame Number,PFN);内核页游一个页表,0号内核线程的进程描述符init_task的成员active_mm指向内存描述符init_mm,内存描述符init_mm的成员pgd指向内核的页全局目录swapper_pg_dir;转换表和内核的页表术语的对应关系:0级转换表对应页全局目录,1级转换表对应页上层目录,2级转换表对应页中间目录,3级转换表对应直接页表;同一种处理器架构在页长度不同的情况可能选择不通的页表级数;
2024-04-06 20:32:01
966
1
原创 不连续页分配器
之后遍历vmap_area_list,在两个相邻vmap_area之间找到一个足够大的空洞,如果找到了,把起始虚拟地址和结束虚拟地址保存在新的vmap_area实例中,将新的vmap_area加入到vmap_area_list中;在这种情况下,如果需要分配长度超过一页的内存块,可以使用不连续页分配器,分配虚拟地址连续但物理地址不连续的内存块;如果虚拟内存区域是使用vmap分配的,vm_struct实例的差别是:成员flags没有设置VM_ALLOC,成员pages是NULL,成员nr_pages是0;
2024-04-05 19:34:40
1084
原创 slab分配器
用户态程序可以使用malloc及其在C标准库中的相关函数申请内存;内核也需要经常分配内存,但无法使用标准库函数;linux内核中,伙伴分配器是一种页分配器,是以页为单位的,但这个单位太大了;如果要分配小块,就需要一个块分配器;slab是内核中一种基本的块分配器;slab分配器在某些情况下表现不太好,Linux内核提供了两个备用的块分配器。1)在配备了大量物理内存的大型计算机上,slab分配器的管理数据结构的内存开销比较大,所以设计了slub分配器;
2024-03-19 17:14:03
838
原创 伙伴分配器
连续的物理页合在一起称为页块(page block);阶(order)是伙伴分配器中的一个专业术语,是页的数量单位,2^n个连续的物理页成为n阶页块;满足以下条件的两个n阶页块称为伙伴(buddy):1、两个页块是相邻的,即物理地址是连续的;2、页块的第一页的物理页号必须是2^n的整数倍;3、如果合并成(n+1)阶页块,第一页的物理页号必须是2^(n+1)的整数倍。这是伙伴分配器(buddy allocator)的名字的来源;
2024-03-01 11:19:53
821
原创 netlink原理及应用
netlink是一种基于网络的通信机制,允许内核内部、内核与用户态应用之间甚至用户态应用之间进行通信;netlink的主要作用是内核与用户态之间通信;它的思想是,基于BSD的socket使用网络框架在内核和用户态之间进行通信;如何在中新增netlink协议?参考nl80211模块初始化时,通过注册通用netlink协议族,将命令以及处理函数进行注册;int err;
2024-03-01 11:00:09
3102
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人