操作系统-锁/内存/中断/IO

文章目录

          • 自旋锁
          • 互斥锁
          • 悲观锁和乐观锁
        • 内存管理
          • 物理/虚拟内存
          • 页表
          • 段表
          • 虚拟内存布局
          • 写时复制copy on write
          • brk,mmap
          • 页面置换算法
        • 中断
          • 中断分类
          • 中断流程
        • 网络I/O
          • I/O模型
          • 服务器处理并发请求

自旋锁

自旋锁是一种基于忙等待(Busy-Waiting)的同步机制。

通过 CPU 提供的 CAS 函数),完成加锁解锁操作:

第一步:查看锁的状态,为空,则执行第二步

第二步:将锁设置为当前线程持有

这两步是原子指令,要么一次性执行完,要么都不执行。

当线程尝试获取锁失败时,它会循环检查锁的状态(“自旋”),直到它拿到锁。

等待时间较短的情况下效率较高,因为避免了线程上下文切换的开销。但长时间等待会导致CPU资源的浪费。

适用于多核系统,且临界区代码执行时间非常短的场景。

互斥锁

在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的锁,确保同一时间只有一个线程访问共享资源。

自旋锁和互斥锁的区别

工作机制:自旋锁在获取不到锁时会一直循环检查,而互斥锁会让线程进入睡眠(挂起)状态,调度其他线程运行。

适用场景:自旋锁适合保护执行时间极的代码段,自旋的代价可能小于线程切换的代价。互斥锁适合保护执行时间较的代码段

性能影响:自旋锁无上下文切换开销,但一直占用CPU,互斥锁挂起唤醒线程产生下上文切换开销,但等待期间CPU执行其他任务,资源利用率更高.

实现复杂度:自旋锁依赖CAS原子操作,不需要操作系统调度,而互斥锁复杂度高,依赖操作系统调度

悲观锁和乐观锁

悲观锁先加锁,再操作

认为并发操作一定会发生冲突,因此每次访问数据时都会加锁,比如synchronized和ReentrantLock

适用写多的场景。

举个例子:出门时锁门(默认有小偷)

乐观锁先操作,提交时再检查冲突

认为并发操作很少发生冲突,只在提交操作时检查是否冲突,比如CAS操作,数据库的乐观锁和Java中的Atomic类。

适用读多写少。

举个例子:

1.购物车结算时才检查库存(默认没人抢购)

2.或者在网上订票,系统显示还有1个座位,你点击预订,系统会先让你填写信息,然后提交的时候检查是否还有座位。如果有,预订成功;如果没有,提示你重新选择

内存管理

计算机系统的核心功能之一,其目标是高效、安全地管理物理内存和虚拟内存资源,确保多个进程能共享内存且互不干扰

物理/虚拟内存
  • 物理内存

    计算机硬件中的实际内存芯片,容量固定,由硬件决定,直接由CPU通过物理地址访问,是程序运行的真实存储空间

  • 虚拟内存

    操作系统为每个进程提供的逻辑地址空间,独立于物理内存,通过通过页表、MMU(内存管理单元,负责管理内存访问和地址转换)、缺页中断等机制管理,将虚拟地址映射到物理地址或磁盘空间。

    • 虚拟内存允许程序使用比物理内存更大的地址空间

    • 每个进程拥有独立的虚拟地址空间,彼此无法直接访问对方内存,避免恶意或错误操作。

      在这里插入图片描述

页表

在这里插入图片描述

操作系统与硬件(如MMU)协作实现虚拟内存的核心数据结构,负责记录虚拟地址到物理地址的映射关系。

核心作用

  1. 地址映射
    将进程的虚拟页号 映射到物理内存的物理页号
  2. 权限控制
    通过页表项的权限位(读/写/执行)限制内存访问。
  3. 状态标记
    记录页是否在物理内存中、是否被修改过等状态信息。

工作流程

  1. 把虚拟内存地址,切分成页号和页内偏移量
  2. 根据页号,从页表里面,查询对应的物理页号
  3. 直接拿物理页号,加上前面的偏移量,就得到了物理内存地址。

如果在页表中没有相应页号,触发缺页中断。此时进入系统内核空间分配物理内存、更新进程页表,最后再返回用户空间,恢复进程的运行。

段表

在这里插入图片描述

虚拟地址也可以通过段表与物理地址进行映射的

  1. 程序的内存空间被划分为多个逻辑段,每个段代表一个逻辑单元
  2. 每个段有独立的基址(起始地址)和界限(长度)
  3. 段的大小可变,与程序逻辑直接对应(例如代码段大小取决于代码量)
  4. 物理地址 = 段基址 + 段内偏移
虚拟内存布局

在这里插入图片描述

1. 代码段

  • 位置:低地址起始(如0x400000)。
  • 内容:编译后的机器指令(可执行代码)。
  • 权限:只读+可执行(防止代码被篡改)。
  • 示例:main函数、库函数的指令。

2. 数据段

  • 位置:紧接代码段。
  • 内容:已初始化的全局变量和静态变量
  • 权限:可读写,不可执行。
  • 示例:int global_var = 42;

3. BSS段

  • 位置:紧接数据段。
  • 内容:未初始化的全局变量和静态变量
  • 权限:可读写
  • 示例:int uninitialized_var;

4. 堆

  • 位置:BSS段之上,向高地址增长。
  • 管理:通过mallocfree动态分配内存。
  • 特点:碎片化问题常见,需手动管理(或依赖垃圾回收)。
  • 示例:int *arr = malloc(100 * sizeof(int));

5. 文件映射区域

  • 位置:堆与栈之间。
  • 内容:
    • 共享库(如libc.solibm.so)。
    • 内存映射文件(通过mmap映射的文件)。
    • 匿名映射(用于大块内存分配,如malloc可能使用mmap)。
  • 权限:按需设置(如可读写、可执行)。

6. 栈

  • 位置:高地址区域(如0x7FFFFFFFFFFFF000),向下增长
  • 内容:函数调用栈帧(局部变量、返回地址、函数参数)。
  • 管理:自动分配/释放内存,由编译器控制。
  • 限制:栈大小固定(默认几MB,可通过ulimit调整)。
  • 示例:int local_var = 10;

7. 内核空间

  • 位置:虚拟地址空间的高位(如64位Linux中高128TB)。
  • 权限:仅内核态可访问,用户进程无权直接读写。
  • 内容:内核代码、数据结构、设备内存映射等。
写时复制copy on write

COW,一种内存管理优化技术,延迟数据的物理拷贝,直到真正需要修改数据时才进行复制。

在这里插入图片描述

  • 问题场景
    假设父进程和子进程共享同一物理内存页(未复制),且子进程修改了某个变量。如果此时父进程读取该变量,会发现值被意外改变。

    • 示例
      父进程定义变量 int x = 42,子进程修改 x = 100。若未复制,父进程的 x 也会变为 100,导致逻辑错误。
  • COW 的解决方案
    当子进程尝试写入 x 时,触发复制,子进程获得独立的物理页副本。

    • 父进程的 x 保持 42,子进程的 x 变为 100,两者互不影响。

具体步骤:

  • 步骤1:共享内存页
    调用 fork() 时,子进程与父进程共享所有物理内存页,页表项标记为只读
  • 步骤2:触发复制
    • 当父进程或子进程尝试写入共享页时,触发缺页中断
    • 操作系统捕获中断,检查触发原因是 COW,执行以下操作:
      1. 分配新的物理页,复制原页内容到新页。
      2. 更新触发写入的进程的页表项,指向新物理页,并标记为可写
      3. 另一进程仍指向原物理页(保持只读,直到其写入时触发复制)。
  • 步骤3:后续操作
    • 修改后的页独立于原页,后续写入不再触发复制。

COW有什么好?

fork()的时候,子进程不需要复制父进程的物理内存,只需要复制父进程的页表,避免了不必要的内存复制开销,这时候父子进程的页表指向的都是共享的物理内存。

只有当父子进程任何有一方对这片共享的物理内存发生了修改操作,这时候才会复制发生修改操作的物理内存。

brk,mmap

int *arr = malloc(100 * sizeof(int))

这里的动态分配内存malloc():

1.如果请求分配的内存<128KB,则通过brk()申请

2.如果请求分配的内存>128KB,则通过mmap()申请

  • brk:修改指针,向高地址移动,获得新内存空间

    在这里插入图片描述

  • mmap:从文件映射区申请一块内存

    在这里插入图片描述

如果物理内存不足

当使用malloc()申请虚拟内存时,如果虚拟内存还没有映射到物理内存,CPU产生缺页中断,缺页中断函数查看是否有空闲物理内存,有则建立虚拟与物理内存的映射,如果没有,则开始回收内存(页面置换/丢弃/终止)

回收内存,包括:

  1. 页面置换
  • 将部分物理内存页换出到磁盘(Swap空间),释放物理内存供其他进程使用。
  1. 释放可丢弃的干净页
  • 直接丢弃未被修改的页(如代码段、文件缓存页),无需写回磁盘。
  1. 终止进程(OOM Killer)
  • 强制终止占用内存过多的进程,释放其所有内存(极端情况下的最后手段)。

1.后台内存回收:唤醒 kswapd 内核线程来回收内存(异步,不阻塞进程执行)

2.直接内存回收:如果异步回收速度跟不上申请内存速度,则直接回收(同步,阻塞进程执行)

哪些内存可以被回收?

  • 文件页

内核缓存的磁盘数据(Buffer)和内核缓存的文件数据(Cache)都叫作文件页。需要读时,重新读取磁盘即可。而如果修改过但还没写入磁盘的数据(脏页)需要先写进磁盘,才进行回收。

  • 匿名页

无实际载体,所以不能直接释放内存。会把不常访问的内存先写到磁盘,再释放这些内存。

如果经过上面的步骤物理内存仍不满足,则触发Out-Of-Memory Killer

  • OOM根据算法杀死一个占用物理内存较高的进程,释放其内存资源
  • 如果依然不满足,继续杀死,直至释放足够物理内存
页面置换算法

页面置换,内存回收的核心手段之一。

选择一个物理页面换出到磁盘,然后把需要访问的页面换入到物理页。

  • 最佳页面OPT

    思想:置换出在未来长时间不会使用的页面

    在这里插入图片描述

  • 先进先出FIFO

    思想:换出在内存中占用时间最长的页面

    在这里插入图片描述

  • 最近最久未使用LRU

    思想:换出前面长时间没有访问过的页面

    在这里插入图片描述

  • 时钟页面LOCK

    思想:将所有页面存在环形链表,每页需要一个访问位(0:未访问1:已访问)

    初始:所有页访问位为0

    缺页时,指针移动,

    ​ 访问位为1:重置为0,指针后移

    ​ 访问位为0:选择,换出内存

    在这里插入图片描述

  • 最不常用LFU

    思想:对每个页面增加一个访问计数器,被访问一次,计数器+1,发生缺页中断时,换出访问次数最少的页面,

中断

计算机系统响应外部或内部事件的机制,允许 CPU 暂停当前任务,转而处理紧急或异步事件(如键盘输入)。处理完后回来继续执行刚才的任务。

中断机制是操作系统实现多任务、设备管理、错误处理等功能的基础

中断分类

外部中断(硬件中断)

  • 触发源:外部设备(如键盘、磁盘、定时器)。
  • 类型:
    • 可屏蔽中断:可通过中断屏蔽位(如 IF 标志)暂时关闭,可随时处理,甚至不处理。
    • 不可屏蔽中断:必须立即处理(如硬件故障、内存校验错误)。

内部中断(软件中断)

  • 触发方式:由程序执行特定指令或发生异常。
    • 异常:同步触发,由 CPU 执行指令时检测到错误(如缺页、除零)交由故障处理程序处理。
    • 陷阱:一般是在编写程序时故意设下的陷阱指令,而后执行到陷阱指令后,CPU将会调用特定程序进行相应的处理,处理结束后返回到陷阱指令的下一条指令。
    • 终止:发生致命错误,不可修复,程序无法继续运行,直接终止。
中断流程
  • 发生中断:设备或程序触发中断,发送信号到 CPU 的中断控制器

  • 中断响应:保存上下文,CPU 暂停当前任务,将程序计数器(PC)、寄存器等压入内核栈,保存当前执行现场,以便处理完中断后恢复执行。

  • 中断处理:CPU根据中断向量表找到对应中断处理程序入口地址,进行中断处理

  • 恢复上下文:继续执行之前的程序

网络I/O
I/O模型

网络I/O模型定义了应用程序如何管理输入和输出操作,尤其是在处理多个并发连接时如何高效利用资源

  1. 阻塞I/O
    • 工作原理:
      应用程序发起I/O操作后,进程会被阻塞,直到数据就绪或操作完成。在此期间,进程无法执行其他任务
    • 优点:
      实现简单,代码直观,适合低并发场景。
    • 缺点:
      每个连接需独立线程/进程,资源消耗大,无法支撑高并发。
    • 适用场景:
      简单的客户端应用或低负载服务(实时性要求不高)。
  2. 非阻塞I/O
    • 工作原理:
      I/O操作立即返回结果(成功或错误),不会被阻塞。若数据未就绪,返回错误,应用需轮询检查状态。
    • 优点:
      单线程可管理多个连接,避免线程阻塞。
    • 缺点:
      轮询消耗CPU资源,延迟较高。
    • 适用场景:
      需要同时处理少量连接且对延迟不敏感的场景(多路复用)。
  3. I/O多路复用
    • 工作原理:
      使用selectpollepoll(Linux)等系统调用,同时等待多个I/O操作,当任一I/O准备就绪时通知应用处理。
    • 优点:
      单线程处理高并发连接,资源利用率高。
    • 缺点:
      事件通知后仍需同步处理I/O,编程复杂度较高。
    • 适用场景:
      Web服务器(如Nginx)、即时通讯等高并发服务。
  4. 信号驱动I/O
    • 工作原理:
      发起I/O请求后继续做其他事情,当I/O操作就绪时,内核发送信号通知处理,应用执行I/O操作
    • 优点:
      避免轮询,减少CPU占用。
    • 缺点:
      信号处理复杂,可能丢失事件,多线程中难以管理。
    • 适用场景:
      需要异步I/O通知的场景,提高系统并发能力。
  5. 异步I/O
    • 工作原理:
      应用发起I/O请求后立即做其他事情,内核完成整个I/O操作后通知应用。
    • 优点:
      无阻塞,资源利用最优,适合高吞吐场景。
    • 缺点:
      实现复杂,需操作系统和库支持,调试困难。
    • 适用场景:
      高并发,高性能场景,减少系统调用,提高系统效率。
服务器处理并发请求
  1. 单线程web服务器

    一次处理一个请求,性能低

  2. 多进程/多线程web服务器

    服务器生成多个进程/线程并行处理多个用户请求,消耗大量系统资源

  3. I/O多路复用web服务器

    只用一个线程处理多个用户请求

  4. 多路复用多线程web服务器

    避免一个进程服务于过多用户请求,生成多个进程,一个进程生成多个线程,每个线程处理一个请求

在这里插入图片描述
考完操作系统不久,结合小林Coding写了些笔记,感谢大家的点赞收藏>W<

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

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

相关文章

割点与其例题

割点 定义&#xff1a; 若一个点在图中被去掉后&#xff0c;图的连通块个数增加&#xff0c;那么这个点就被称为“割点”。如下图所示红点。 定义说白了就是若去掉一个点&#xff0c;图被“断开”的点称为割点。 朴素算法&#xff1a; 枚举每个点 u。遍历图&#xff0c;如果…

图卷积神经网络(Graph Convolutional Network, GCN)

最近看论文看到了图卷积神经网络的内容&#xff0c;之前整理过图神经网络的内容&#xff0c;这里再补充一下&#xff0c;方便以后查阅。 图卷积神经网络&#xff08;Graph Convolutional Network, GCN&#xff09; 图卷积神经网络1. 什么是图卷积神经网络&#xff08;GCN&#…

安装win11硬盘分区MBR还是GPT_装win11系统分区及安装教程

最近有网友问我,装win11系统分区有什么要求装win11系统硬盘分区用mbr还是GPT&#xff1f;我们知道现在的引导模式有uefi和legacy两种引导模式&#xff0c;如果采用的是uefi引导模式&#xff0c;分区类型对应的就是gpt分区(guid)&#xff0c;如果引导模式采用的是legacy&#xf…

服务培训QDA 的安装调试方法,硬件模块的讲解和软件控制台使用及系统测试

#服务培训##质谱仪##软件控制##硬件模块# 以下是关于Waters QDa单杆液质质谱仪的安装调试、硬件模块讲解以及软件控制台使用培训的相关内容&#xff1a; 安装调试 场地准备&#xff1a;用户需要提前准备好实验室&#xff0c;确保实验室环境符合仪器的要求&#xff0c;如温度、…

在K8S集群中部署EFK日志收集

目录 引言环境准备安装自定义资源部署ElasticsearchMaster 节点与 Data 节点的区别生产优化建议安装好以后测试ES是否正常部署Fluentd测试filebeat是否正常推送日志部署Kibana获取账号密码&#xff0c;账号是&#xff1a;elastic集群测试 引言 系统版本为 Centos7.9内核版本为…

polarctf-web-[rce1]

考点&#xff1a; (1)RCE(exec函数) (2)空格绕过 (3)执行函数(exec函数) (4)闭合(ping命令闭合) 题目来源&#xff1a;Polarctf-web-[rce1] 解题&#xff1a; 这段代码实现了一个简单的 Ping 测试工具&#xff0c;用户可以通过表单提交一个 IP 地址&#xff0c;服务器会执…

【串流VR手势】Pico 4 Ultra Enterprise 在 SteamVR 企业串流中无法识别手势的问题排查与解决过程(Pico4UE串流手势问题)

写在前面的话 此前&#xff08;用Pico 4U&#xff09;接入了MRTK3&#xff0c;现项目落地需要部署&#xff0c;发现串流场景中&#xff0c;Pico4UE的企业串流无法正常识别手势。&#xff08;一体机方式部署使用无问题&#xff09; 花了半小时解决&#xff0c;怕忘&#xff0c;…

ES(Elasticsearch)的应用与代码示例

Elasticsearch应用与代码示例技术文章大纲 一、引言 Elasticsearch在现代化应用中的核心作用典型应用场景分析&#xff08;日志分析/全文检索/数据聚合&#xff09; 二、环境准备(前提条件) Elasticsearch 8.x集群部署要点IK中文分词插件配置指南Ingest Attachment插件安装…

临床决策支持系统的提示工程优化路径深度解析

引言 随着人工智能技术在医疗领域的迅猛发展,临床决策支持系统(CDSS)正经历从传统规则引擎向智能提示工程的范式转变。在这一背景下,如何构建既符合循证医学原则又能适应个体化医疗需求的CDSS成为医学人工智能领域的核心挑战。本报告深入剖析了临床决策支持系统中提示工程的…

火山RTC 8 SDK集成进项目中

一、SDK 集成预备工作 1、SDK下载 https://www.volcengine.com/docs/6348/75707 2、解压后 3、放在自己项目中的位置 1&#xff09;、include 2&#xff09;、lib 3)、dll 暂时&#xff0c;只需要VolcEngineRTC.dll RTCFFmpeg.dll openh264-4.dll&#xff0c; 放在intLive2…

OkHttp用法-Java调用http服务

特点&#xff1a;高性能&#xff0c;支持异步请求&#xff0c;连接池优化 官方文档&#xff1a;提供快速入门指南和高级功能&#xff08;如拦截器、连接池&#xff09;的详细说明&#xff0c;GitHub仓库包含丰富示例。 社区资源&#xff1a;中文教程丰富&#xff0c;GitHub高…

python中常用的参数以及命名规范

以下是 Python 中常见的命名规范、参数用法及在大型项目中常用的操作模式&#xff0c;供记录参考&#xff1a; 1. 命名规范&#xff08;Naming Conventions&#xff09; 前缀/形式含义示例_age单下划线&#xff1a;弱“私有”标记&#xff08;可访问但不建议外部使用&#xff…

第五十七篇 Java接口设计之道:从咖啡机到智能家居的编程哲学

目录 引言&#xff1a;生活中的接口无处不在一、咖啡机与基础接口&#xff1a;理解抽象契约1.1 咖啡制作的标准接口 二、智能家居与策略模式&#xff1a;灵活切换实现2.1 温度调节策略场景 三、物流系统与工厂模式&#xff1a;标准接口下的多样实现3.1 快递运输接口设计 四、健…

第二十六天打卡

全局变量 global_var 全局变量是定义在函数、类或者代码块外部的变量&#xff0c;它在整个程序文件内都能被访问。在代码里&#xff0c; global_var 就是一个全局变量&#xff0c;下面是相关代码片段&#xff1a; print("\n--- 变量作用域示例 ---") global_var …

联合查询

目录 1、笛卡尔积 2、联合查询 2.1、内连接 2.2、外连接 1、笛卡尔积 笛卡尔积&#xff1a; 笛卡尔积是让两个表通过排列组合的方式&#xff0c;得到的一个更大的表。笛卡尔积的列数&#xff0c;是这两个表的列数相加&#xff0c;笛卡尔积的行数&#xff0c;是这两个表的行…

【HTML5学习笔记2】html标签(下)

1表格标签 1.1表格作用 显示数据 1.2基本语法 <table><tr> 一行<td>单元格1</td></tr> </table> 1.3表头单元格标签 表头单元格会加粗并且居中 <table><tr> 一行<th>单元格1</th></tr> </table&g…

window 显示驱动开发-分页视频内存资源

与 Microsoft Windows 2000 显示驱动程序模型不同&#xff0c;Windows Vista 显示驱动程序模型允许创建比可用物理视频内存总量更多的视频内存资源&#xff0c;然后根据需要分页进出视频内存。 换句话说&#xff0c;并非所有视频内存资源都同时位于视频内存中。 GPU 的管道中可…

《C 语言指针高级指南:字符、数组、函数指针的进阶攻略》

目录 一. 字符指针变量 二. 数组指针变量 三. 二维数组传参 3.1 二维数组的本质 3.2 访问方式与地址计算 3.3 二维数组的传参方式 3.4 深入解析 *(*(arri)j) 与 arr[i][j] 的等价性 四. 函数指针变量 4.1 函数指针变量的创建 4.2 函数指针变量的使用 4.3 两段"…

Unity:场景管理系统 —— SceneManagement 模块

目录 &#x1f3ac; 什么是 Scene&#xff08;场景&#xff09;&#xff1f; Unity 项目中的 Scene 通常负责什么&#xff1f; &#x1f30d; 一个 Scene 包含哪些元素&#xff1f; Scene 的切换与管理 &#x1f4c1; 如何创建与管理 Scenes&#xff1f; 什么是Scene Man…

内容中台重构企业知识管理路径

智能元数据驱动知识治理 现代企业知识管理的核心挑战在于海量非结构化数据的有效治理。通过智能元数据分类引擎&#xff0c;系统可自动识别文档属性并生成多维标签体系&#xff0c;例如将技术手册按产品版本、功能模块、适用场景进行动态标注。这种动态元数据框架不仅支持跨部…