操作系统原理简要介绍

news2025/4/23 16:14:16

文章目录

      • 计算机启动的底层流程(从裸机到操作系统)
      • 内核
        • 用户态与内核态
        • 内核分类
      • 进程与线程:操作系统的 “执行者”
      • 内存管理:数据的“存储与调度”
      • 文件系统:数据的“组织与持久化”
      • 设备驱动:硬件的“翻译官”
      • 典型操作系统架构对比
      • 名称解释
      • Unix 常用编程接口速查表

操作系统(OS)是计算机系统的“灵魂”,它不仅是硬件与软件之间的桥梁,更是管理计算机资源、控制程序运行的核心。

操作系统通过分层抽象将复杂硬件转化为易用的服务:

  1. 硬件层:提供原始计算资源(CPU、内存、IO)。
  2. 内核层:通过进程管理、内存管理、文件系统等模块封装硬件细节,提供基础服务。
  3. 系统调用层:以API形式向上层暴露功能(如read()读取文件)。
  4. 用户层:通过应用程序和界面让用户与计算机交互。

分层结构既保证了底层效率(如内核直接操作硬件),又提升了上层易用性(用户无需关心二进制指令)。理解这些结构,能帮助我们更好地分析系统性能问题(如内存泄漏)、优化程序设计(如合理使用多线程)。以下是操作系统的典型架构结构图:

用户层(应用程序)
├─ 图形界面(GUI):如Windows桌面、Linux的GNOME
├─ 命令行界面(CLI):如CMD、Bash
├─ 应用程序:浏览器、办公软件、游戏
│
├─ 系统调用层(API接口)
│  ├─ 进程管理:fork()、exec()
│  ├─ 内存管理:malloc()、free()
│  ├─ 文件操作:open()、read()、write()
│  └─ 设备控制:ioctl()
│
├─ 内核层(核心功能)
│  ├─ 进程调度(Scheduler):决定哪个进程使用CPU
│  ├─ 内存管理(Memory Manager):虚拟内存、分页机制
│  ├─ 文件系统(File System):EXT4、NTFS等
│  ├─ 设备驱动(Device Drivers):键盘、硬盘、显卡驱动
│  └─ 进程间通信(IPC):管道、共享内存、消息队列
│
└─ 硬件层(物理设备)
   ├─ CPU:执行指令,支持特权级(用户态/内核态)
   ├─ 内存(RAM):存储正在运行的程序和数据
   ├─ 外存(硬盘/SSD):持久化存储文件
   ├─ 输入输出设备(IO):键盘、鼠标、显示器、网卡
   └─ 总线(Bus):连接各硬件的通信通道

从应用程序到硬件流程示例

graph TD
用户操作[点击“打开文件”] --> 应用程序[调用open("/data.txt", "r")]
应用程序 --> 系统调用[触发sys_open系统调用]
系统调用 --> 内核[文件系统模块查找inode]
内核 --> 驱动[硬盘驱动发送读取扇区命令]
驱动 --> 硬件[硬盘磁头定位扇区,返回数据]
硬件 --> 内核[将数据存入内存缓冲区]
内核 --> 应用程序[返回文件句柄,应用程序读取数据]

操作系统的本质是对计算机资源(CPU、内存、存储、IO设备等)的高效管理与抽象

  • 高效性:通过调度算法、缓存机制(如CPU缓存、页缓存)提升资源利用率。
  • 公平性:确保每个程序都能合理获得资源(如防止某个进程长期占用CPU)。
  • 易用性:通过图形界面、API接口(如Windows的Win32 API、Linux的系统调用)隐藏底层复杂性,让用户和开发者无需关心硬件细节。

计算机启动的底层流程(从裸机到操作系统)

  1. BIOS/UEFI阶段

    • CPU复位后从0xFFFF0地址执行ROM中的BIOS代码
    • POST(Power-On Self Test)硬件自检:检测内存、外设等关键硬件
    • 加载MBR/GPT分区表的首个扇区(512字节)到0x7C00内存地址
  2. Bootloader阶段

    • GRUB/LILO等引导程序接管控制权
    • 实模式→保护模式切换(CR0寄存器第0位置1)
    • 加载内核映像到内存:vmlinuz文件解压到0x100000地址
  3. 内核初始化

    • 初始化IDT(中断描述符表)、GDT(全局描述符表)
    • 建立页表(四级页表结构:PGD→PUD→PMD→PTE)
    • 启动init进程(PID=1):即启动第一个用户进程,现代系统通常为init/systemd

内核

内核是操作系统的核心程序,直接运行在硬件之上,负责管理底层资源并为上层软件提供服务。主要包括进程管理、内存管理、文件系统、设备驱动等核心模块。

用户态与内核态

为防止应用程序误操作或恶意破坏系统(如直接修改内存、篡改硬件时钟);隔离用户程序与内核,即使某个应用崩溃也不会导致整个系统宕机。使内核统一管理硬件资源,避免多个程序竞争操作同一设备。操作系统通过权限区分分设两种核心的运行模式,用户态内核态

  • 用户态(User Mode):程序运行在低权限模式(如Intel CPU的Ring 3),只能执行非特权指令(如算术运算),无法直接操作硬件或访问敏感内存区域。 用户态程序只能访问自己的虚拟内存空间(如Linux中0~3GB的虚拟地址),需通过系统调用请求内核服务。
  • 内核态(Kernel Mode):运行在高权限模式(如Ring 0),可执行所有指令(包括I/O操作、内存管理),直接控制硬件和内核数据结构,管理进程调度、中断处理等核心任务。
  • 切换方式:通过系统调用(如Linux的syscall)、硬件中断(如键盘按键)或异常处理时,触发从用户态进入内核态的切换。频繁切换(如高并发网络请求)可能导致CPU时间浪费在状态切换而非实际计算。(一次切换约需100-1000纳秒)。
内核分类

根据架构不同,内核可分为两类:

  1. 单片内核(Monolithic Kernel)

    • 特点:所有功能(如内存管理、进程调度、设备驱动)集成在一个内核程序中,运行在最高特权级(如x86的Ring 0)。
    • 优势:效率高。模块间直接函数调用,避免用户态与内核态切换开销。 适合对性能要求高的场景(如Linux、早期Windows)。
    • 风险及挑战:一个模块出错可能导致整个系统崩溃(需严格测试)。内核体积庞大(Linux内核源码超2000万行),调试难度高,需通过Kasan等工具检测内存错误。
    • 典型案例:Linux内核
      • 虽为单片内核,却通过动态加载模块(Loadable Kernel Modules, LKM)实现模块化扩展。例如:
      • 网卡驱动可作为模块动态加载,无需重启内核;
      • 文件系统(如NTFS、FAT)以模块形式存在,支持按需加载。
  2. 微内核(Micro Kernel)

    • 特点:仅保留最核心功能(如进程调度、内存管理、IPC通信),其他功能(如文件系统、网络协议)作为用户态服务运行。
    • 优势:结构清晰,扩展性强(新增功能无需修改内核),稳定性高(用户态服务崩溃不影响内核)。 代表:QNX(车载系统)、Minix、Windows NT内核(部分微内核设计思想)。
    • 典型案例:QNX(车载系统)
      • 内核仅包含进程调度、内存管理、IPC(进程间通信),其他功能如文件系统、网络协议均为用户态服务。
      • 进程间通信(IPC)机制
        • 消息传递(Message Passing):进程间通过内核中转消息,需序列化/反序列化数据(如将结构体转为字节流)。
        • 共享内存(Shared Memory):开辟内核管理的公共内存区域,进程通过指针直接访问(需配合锁机制)。
      • 性能优化
        • 采用零拷贝(Zero-Copy)技术:如网络数据直接从内核缓冲区复制到用户态,避免多次拷贝(传统方式需经内核缓冲区→用户缓冲区→应用程序)。
  3. 混合内核(Hybrid Kernel)

    • 代表:Windows 10内核
      • 核心组件(如内存管理、进程调度)运行在内核态,部分服务(如驱动程序)可在用户态运行(通过**内核态驱动验证器(KMDF)**隔离风险)。
      • 特权级扩展:引入**用户态辅助库(如Win32k.sys)**处理图形界面请求,减少内核态代码量,提升稳定性。

可以通过如下理解内核的几大组件的工作内容:
(进程管理)任务分配:多个程序同时运行时,如何让 CPU 轮流处理?
(内存管理与文件系统)仓库管理:内存不够用怎么办?如何快速找到硬盘里的文件?
(设备驱动与通信机制)跨部门协作:键盘输入如何传给程序?显卡如何显示数据?

进程与线程:操作系统的 “执行者”

1. 进程(Process)

  • 定义:正在运行的程序的实例,是操作系统资源分配的最小单位。
  • 组成
    • 进程控制块(PCB):记录进程状态(运行/就绪/阻塞)、优先级、内存地址等信息。
    • 程序代码:执行的指令集合。
    • 数据集合:程序运行时的输入输出、变量等数据。
  • 状态切换
    • 运行态:占用CPU执行指令。
    • 就绪态:等待CPU调度(就绪队列中排队)。
    • 阻塞态:因等待IO、锁等资源暂停(进入阻塞队列)。

进程控制块(PCB)数据结构

struct task_struct {
    volatile long state;    // -1不可运行, 0可运行, >0已停止
    void *stack;            // 内核栈指针
    struct mm_struct *mm;   // 内存描述符
    pid_t pid;              // 进程标识符
    struct files_struct *files; // 打开文件表
    // ...包含200+字段(Linux 5.x版本)
};

2. 线程(Thread)

  • 定义:进程内的最小执行单元,共享进程的资源(如内存、文件句柄)。

  • 优势

    • 轻量级:创建/销毁开销远小于进程。
    • 高并发:多个线程可并行执行(依赖多核CPU),提升程序效率(如浏览器多标签页)。
  • 挑战:线程间共享数据需解决竞态条件(Race Condition),需通过锁(Mutex)、信号量(Semaphore)等机制保证同步。

  • 进程相当于独立工厂车间(如浏览器车间、文档编辑车间),每个车间有独立工具柜(内存空间);

  • 线程是车间里的工人(如浏览器车间有网络请求工人、页面渲染工人)共享车间资源。

3. 调度算法
有个计算机CPU硬件个数是固定的,而计算机上运行通常运行很多的进行和线程,从而就需要CPU调度算法决定当下时刻分配哪个CPU给哪个进程/线程。

  • 作用:决定哪个进程/线程获得CPU资源。
  • 常见算法
    • 先来先服务(FCFS):按就绪顺序调度,简单但可能导致“饥饿”(高优先级任务等待)。
    • 短作业优先(SJF):优先运行执行时间短的任务,提升吞吐量。
    • 轮转调度(Round Robin):每个任务分配固定时间片(如10ms),时间到则切换,保证公平性(适用于分时系统)。
    • 优先级调度:为任务分配优先级(如实时任务优先级高于普通任务),避免低优先级任务长期等待。

4. 上下文切换(Context Switch)

  • 保存当前进程的CPU状态(如寄存器值、程序计数器PC)到PCB;
  • 从就绪队列中选择下一个进程,将其PCB中的状态加载到CPU;
  • 更新MMU页表,切换内存地址空间(确保新进程访问自己的虚拟内存)。

内存管理:数据的“存储与调度”

内存(RAM)是程序运行的临时空间,操作系统需解决内存分配、回收、保护、虚拟地址映射等问题。
操作系统的虚拟地址机制是现代内存管理的核心设计,其根本目的是为每个进程创造独立且连续的逻辑内存视图,同时解决物理内存碎片化、安全性及多任务隔离等关键问题。其实现原理可分为三个层次:硬件支持(MMU内存管理单元)、数据结构(页表与多级映射)和操作系统调度(缺页中断处理)。当进程访问内存时,CPU通过虚拟地址访问数据,MMU会实时将虚拟地址转换为物理地址——这个过程会先查询TLB快表(缓存常用页表项),若未命中则逐级查询页表(如x86的四级页表),最终通过页表项中的物理页框号完成地址转换。若目标页面尚未加载到内存(页表项标记为不存在),则触发缺页中断,由操作系统从磁盘Swap空间或文件系统中加载所需数据页,并更新页表完成映射。这种机制不仅实现了进程间的内存隔离(防止越权访问),还通过分页技术支撑了远超物理内存容量的虚拟空间,并通过Copy-on-Write等优化策略提升内存利用率,是操作系统稳定性和高效能的重要保障。

1. 虚拟内存(Virtual Memory)

  • 原理:将内存与外存(如硬盘)结合,为每个进程分配独立的虚拟地址空间(如32位系统中每个进程默认有4GB虚拟地址)。
  • 好处
    • 隔离性:进程间虚拟地址空间隔离,避免互相干扰(一个进程崩溃不影响其他进程)。
    • 大内存支持:允许运行大于物理内存的程序(通过分页机制将不常用数据交换到硬盘)。
  • 核心机制
    • 分页(Paging):将虚拟内存和物理内存划分为固定大小的页(Page,如4KB),通过页表(Page Table)记录虚拟页与物理页的映射关系。
    • 缺页中断(Page Fault):当访问的虚拟页不在物理内存中时,触发中断并从硬盘加载对应页。

2. 内存分配策略

  • 静态分配:程序运行前分配固定内存(适用于简单系统,如嵌入式设备)。
  • 动态分配:程序运行时按需申请内存(如C语言的malloc),需解决碎片问题(内存碎片化导致无法分配大内存块)。
    • 首次适应(First Fit):找到第一个足够大的空闲块分配,简单但可能产生外部碎片。
    • 最佳适应(Best Fit):选择最接近需求的空闲块,可能产生大量微小碎片。
    • 伙伴系统(Buddy System):将内存划分为2的幂次块(如4KB、8KB、16KB),减少碎片(Linux内核采用)。
  • 关键组件
    • 页表(Page Table):记录虚拟页与物理页的映射关系(如虚拟地址0x1234映射到物理地址0x5678)。
    • MMU(内存管理单元):硬件模块,负责虚拟地址到物理地址的转换。
    • TLB(转换后备缓冲器):缓存最近使用的页表项,加速地址转换(类似CPU缓存)。

文件系统:数据的“组织与持久化”

文件系统负责管理硬盘等存储设备上的数据,定义了数据的存储格式、目录结构、访问权限等。
1. 核心概念

文件系统
├─ 超级块(Super Block):记录文件系统元信息(总块数、空闲块数、inode总数)
├─ inode表:存储每个文件的元数据(权限、大小、数据块指针)
├─ 数据块(Data Block):实际存储文件数据
└─ 目录项(Directory Entry):文件名与inode的映射(如“photo.jpg”→ inode 123)
  • inode与block(以Linux为例):
    • inode:存储文件元信息(如大小、权限、修改时间、数据块指针),每个文件对应一个inode。
    • Data block:实际存储数据的物理块(如4KB),通过inode中的指针找到数据所在的block。
  • 目录:本质是存储文件名与inode映射关系的特殊文件。
  • 访问流程:访问文件/user/doc.txt时,先通过超级块找到根目录的inode,再通过目录项找到doc.txt的inode,最后根据inode中的数据块指针读取数据。

2. 常见文件系统

  • FAT32:简单兼容好,但不支持大文件(单个文件最大4GB)和复杂权限管理(适用于U盘)。
  • NTFS(Windows):支持大文件、文件加密、压缩、日志功能(记录操作以便故障恢复)。
  • EXT4(Linux):高性能、支持超大文件(1EB)、延迟分配(提升写入效率)。
  • APFS(macOS):基于日志,支持快照(Snapshot)、空间共享(多个文件共享相同数据块)。

3. 磁盘调度算法

  • 作用:优化磁盘读写顺序,减少寻道时间(磁头移动耗时)。
  • 常见算法
    • 最短寻道时间优先(SSTF):优先处理离当前磁头最近的请求,可能导致“饥饿”。
    • 电梯算法(SCAN):磁头单向移动,处理所有请求后反向(类似电梯运行),平衡公平性与效率。

设备驱动:硬件的“翻译官”

操作系统通过设备驱动程序(Driver)与硬件交互,驱动程序负责:

  • 初始化硬件:如显卡、网卡的启动配置。
  • 处理IO请求:将上层软件的读写请求转换为硬件可识别的指令(如向硬盘发送扇区读写命令)。
  • 中断处理:当硬件完成操作时(如键盘按键按下),通过中断信号通知内核,触发相应处理程序。
  • 特点:需与硬件寄存器、中断号等底层细节打交道,通常运行在内核态,对稳定性要求极高(驱动崩溃可能导致系统蓝屏)。

典型操作系统架构对比

以下是Linux类、Windows和安卓操作系统的结构差异表:

操作系统内核类型系统层次结构文件系统进程间通信方式用户界面特点底层基于的系统
Linux类单片内核为主(部分支持微内核如L4)内核层(硬件管理)→ Shell层(用户接口)→ 文件系统层(存储管理)→ 应用程序层EXT4/XFS/Btrfs等管道/信号/共享内存/Socket等命令行(CLI)+ 可定制图形界面(GNOME/KDE等)直接基于Unix理论设计
Windows混合内核(微内核思想+单片实现)用户层(应用/图形界面/服务)→ 内核层(执行体/硬件抽象层/驱动)NTFS/FAT32等消息传递/COM/命名管道等统一图形界面(窗口化操作+鼠标交互)独立设计(非Unix体系)
安卓(Android)基于Linux内核(定制版)Linux核心层(硬件驱动)→ 系统运行库层(C/C++库+ART)→ 应用框架层→ 应用层F2FS/EXT4(针对闪存优化)Binder机制/Intent/Broadcast等触摸优化图形界面(Material Design风格)Linux内核(类Unix)
  1. 底层基于的系统差异

    • Linux类:设计理念直接继承Unix(多用户、多任务、分层架构),但代码独立开发,属于类Unix系统。
    • Windows:从早期MS-DOS发展而来,架构完全独立于Unix,属于非Unix体系操作系统。
    • 安卓:底层内核基于Linux(类Unix),但上层框架(如Java运行环境、应用生态)完全自研,因此归类为“基于Linux内核的类Unix系统”。
  2. 内核与层次结构的关联

    • Linux的单片内核效率高但复杂度高,Windows的混合内核平衡了稳定性和性能,安卓则通过Linux内核兼容硬件,再叠加自研框架实现移动生态。
  3. 文件系统特性

    • Linux支持多种高性能文件系统,Windows的NTFS强调安全性和可靠性,安卓的F2FS针对闪存寿命和读写速度优化。

名称解释

术语/组件全称定义与解释作用与典型场景
操作系统(OS)-管理计算机软硬件资源的底层系统软件,负责资源分配、调度、内存管理等,是用户与硬件的接口。用户通过操作系统使用计算机,如在Windows上办公、在Linux服务器上运行程序。
内核(Kernel)-操作系统的核心,运行在最高特权级,管理CPU、内存、设备驱动等底层功能。有单片内核、微内核、混合内核等类型。负责底层资源管理,如Linux内核处理进程调度、内存分配。
用户态 vs 内核态-用户态是应用程序运行的低特权级模式,需通过系统调用请求内核服务;内核态是内核代码运行的高特权级模式,可直接操作硬件和内存。用户态保证系统安全,内核态确保系统高效运行,如浏览器运行在用户态,磁盘读写由内核态完成。
进程(Process)-正在运行的程序实例,是资源分配的基本单位,包含代码、数据、进程控制块等。一个运行的浏览器窗口就是一个进程,操作系统为其分配内存等资源。
线程(Thread)-进程内的执行单元,是调度的基本单位,同一进程内线程共享内存。浏览器中多个标签页可由不同线程处理,提高响应速度。
进程调度(Scheduler)-内核根据算法从就绪队列选进程/线程分配CPU资源,算法有先来先服务、短作业优先等。多个程序同时运行时,调度器决定哪个先执行,如优先处理紧急任务。
内存管理-负责内存分配、回收和保护,包括虚拟内存和内存保护机制。虚拟内存让程序使用比实际物理内存更大的空间,内存保护防止进程越界访问。
文件系统(File System)-定义文件存储结构、访问方式和数据组织形式,有日志文件系统、分布式文件系统等。用户通过文件系统存储和读取文件,如在Windows上用NTFS保存文档。
设备驱动(Device Driver)-内核中与硬件设备通信的程序,屏蔽硬件差异,提供统一接口。连接鼠标、键盘等设备后,驱动程序让操作系统能识别和使用它们。
系统调用(System Call)-用户态程序请求内核服务的接口,是用户态与内核态交互的合法途径。程序使用系统调用进行文件读写、进程创建等操作。
进程间通信(IPC)-不同进程交换数据的机制,有管道、共享内存、消息传递、远程过程调用等。多个进程协作时,如数据库服务器和客户端通过IPC交换数据。
中断(Interrupt)-硬件或软件发出的信号,通知内核处理异步事件,分硬件中断和软件中断。键盘按键触发硬件中断,系统调用触发软件中断。
虚拟文件系统(VFS)-内核中抽象的文件系统接口,支持多种文件系统,提供统一操作接口。无论使用EXT4还是FAT32,程序都能通过VFS进行文件操作。
shell-用户与操作系统交互的命令行接口,解析用户命令并调用内核功能。用户在Linux终端输入命令,shell负责执行。
分页(Paging)-虚拟内存管理方式,将内存划分为固定大小的页,通过页表映射逻辑和物理地址。操作系统利用分页高效管理内存,如将程序的不同部分分页存储。
分段(Segmentation)-早期内存管理方式,将程序划分为不同段,每个段有独立逻辑地址空间。用于程序模块化设计,如代码段和数据段分开。
死锁(Deadlock)-多个进程竞争资源形成循环等待状态,若不干预无法继续执行,可通过预防、避免等方法解决。多个程序同时竞争有限资源时可能发生死锁,如两个程序互相等待对方释放资源。
并发与并行-并发是多个进程/线程在同一时间段交替执行,并行是在同一时刻同时执行。单核CPU实现并发,多核CPU实现并行,如多个程序在单核电脑上轮流执行,在多核电脑上同时执行。
守护进程(Daemon)-在后台持续运行的系统进程,无需用户交互,负责监控系统服务。如Linux的系统日志守护进程记录系统运行信息。
PCB进程控制块(Process Control Block)内核为每个进程维护的结构体,存储进程元数据,是进程存在的标识。包含状态、调度信息、内存指针等。进程切换时保存和恢复状态,调度器根据其信息决定执行顺序。
VMA虚拟内存区域(Virtual Memory Area)进程虚拟地址空间中连续的内存区域,描述程序不同部分。有起始/结束地址、访问权限等属性。判断内存访问是否合法,动态内存分配时扩展堆空间。
TLB转换后备缓冲器(Translation Lookaside Buffer)CPU内部高速缓存,存储最近的虚拟到物理地址映射。CPU先查TLB,命中则直接访问内存,未命中则查页表。提升内存访问速度,TLB命中率影响性能,如数据库使用大页提高命中率。
MMU内存管理单元(Memory Management Unit)CPU中的硬件模块,负责虚拟地址到物理地址的转换,支持内存保护和权限控制。实现虚拟内存,配合TLB加速地址转换,隔离进程地址空间。
页表(Page Table)-存储虚拟页与物理页映射关系的数据结构,通常是多级结构。页表项包含物理页帧号和标志位。内核通过修改页表分配和回收内存,内存回收时可能触发缺页中断。
缺页中断(Page Fault)-进程访问的虚拟页不在物理内存中时,由MMU触发的硬件中断,内核处理。分良性和恶性缺页。实现虚拟内存,程序无需关心数据是否在内存,内存紧张时触发内存回收。
CPU上下文切换-保存当前进程CPU状态,恢复下一个进程状态的过程。包括保存上下文、更新页表、刷新TLB、加载新上下文等步骤。是多任务调度基础,切换频繁会降低系统性能。
伙伴系统(Buddy System)-内核管理物理内存分配的算法,将空闲内存按2的幂次大小分组,分配时找最接近需求的最小块,相邻空闲块可合并。用于分配连续物理内存,与slab分配器配合提升内存利用率。
slab分配器-针对内核小对象的内存分配器,为每种对象类型创建缓存,对象释放时放回缓存。减少小对象分配碎片,支持对象构造/析构函数,提升内核对象管理效率。
快表(Translation Cache)即TLB(转换后备缓冲器)见前表TLB描述。-
段页式管理-结合分段与分页的内存管理方式:先将程序划分为段(如代码段、数据段),再将每个段划分为页。- 早期大型机(如IBM System/370)使用,现代系统较少见,但Linux仍支持分段作为分页的补充。
交换空间(Swap Space)-磁盘上用于存储虚拟内存中换出页的区域,当物理内存不足时,将不活跃页写入交换空间。- 笔记本电脑内存不足时,系统自动将后台程序数据写入Swap,避免直接崩溃。
颠簸(Thrashing)-因频繁缺页中断导致CPU大部分时间用于页面换入换出,而非执行程序,系统性能急剧下降。- 进程数过多或分配内存不足时易发生,需通过增加物理内存或调整调度参数缓解。
文件描述符(File Descriptor, FD)-操作系统为打开文件分配的整数句柄,用于标识文件读写位置、权限等状态。- Linux中0(标准输入)、1(标准输出)、2(标准错误)是预定义文件描述符。
管道(Pipe)-一种半双工的IPC机制,数据只能单向流动,通常用于父子进程间通信(如`lsgrep “txt”`)。
命名管道(Named Pipe)FIFO有名称的管道,支持跨进程通信(无需亲缘关系),数据先入先出(FIFO)。- 客户端与服务器通过命名管道交换数据(如数据库服务进程与客户端进程)。
信号(Signal)-用于通知进程异步事件的简单消息(如键盘按下Ctrl+C发送SIGINT信号终止程序)。- 实现进程间异步通知,如kill -9 <pid>发送SIGKILL强制终止进程。
信号量(Semaphore)-用于控制多进程/线程对共享资源访问的计数器,分为二进制信号量(0/1)和计数信号量- 控制线程对临界资源的访问(如多个线程同时写入日志文件时,用信号量保证互斥)。
互斥锁(Mutex)互斥量(Mutual Exclusion)保证在任意时刻只有一个线程/进程访问临界资源的同步机制,获取锁失败时阻塞等待。- 多线程访问共享变量(如计数器)时加锁,避免竞态条件(如银行账户余额并发修改)。
读写锁(Read-Write Lock)-允许多个读操作并发执行,但写操作独占的锁,适用于“多读少写”场景(如缓存数据读取)。- 数据库查询时允许多个线程并发读数据,写数据时独占锁,提升并发性能。
临界区(Critical Section)-程序中访问共享资源的代码段,同一时刻只能有一个进程/线程进入。- 多线程操作共享链表时,链表遍历和修改代码需置于临界区内,确保数据一致性。
银行家算法(Banker’s Algorithm)-一种死锁避免算法,通过模拟资源分配过程,确保系统始终处于“安全状态”(存在资源分配顺序避免死锁)。- 操作系统动态分配资源时(如内存、打印机),预防死锁发生(如银行授信避免坏账)。
优先级反转(Priority Inversion)-高优先级进程因等待低优先级进程持有的资源而被阻塞,导致低优先级进程优先运行的现象。- 实时系统(如嵌入式控制)中需通过优先级继承(低优先级进程临时提升至高优先级)解决。
实时操作系统(RTOS)Real-Time OS能在确定时间内响应外部事件并完成任务的操作系统,分为硬实时(绝对时限)和软实时(最佳努力)。- 工业控制(如机器人)、航空航天(如飞行控制系统)需硬实时系统,手机闹钟为软实时。
抢占式调度(Preemptive Scheduling)-调度器可强制中断正在运行的进程,将CPU分配给更高优先级进程(如Linux的CFS调度器)。- 保证高优先级任务及时执行(如视频会议进程抢占后台下载任务的CPU资源)。
非抢占式调度(Non-Preemptive Scheduling)-进程运行直到主动放弃CPU(如完成任务或等待IO),调度器不强制中断(如早期Windows 3.x)。- 实现简单但实时性差,适用于批处理系统(如服务器后台任务)。
地址空间布局随机化(ASLR)Address Space Layout Randomization程序加载时随机化其虚拟地址空间的基址(如堆、栈、共享库的起始地址),增加黑客攻击难度。- 现代操作系统(如Windows、Linux)默认开启ASLR,防御缓冲区溢出攻击。
内存屏障(Memory Barrier)-强制编译器和CPU按指定顺序执行内存操作的指令,用于解决缓存一致性和指令重排序问题。- 多处理器系统中确保线程间数据可见性(如Java的volatile关键字底层使用内存屏障)。
超级块(Super Block)-文件系统的元数据块,存储文件系统类型、总块数、空闲块数、inode总数等关键信息。- 格式化硬盘时创建超级块,系统挂载文件系统时首先读取超级块(如EXT4的super_block)。
inode索引节点(Index Node)文件系统中存储文件元数据的结构体,包含文件权限、大小、创建时间、数据块指针等,不包含文件名。- 文件名通过目录项与inode关联,删除文件实际是删除目录项,inode引用计数为0时释放数据块。
高速缓存(Cache)-位于CPU与内存之间的高速存储单元,用于缓存频繁访问的数据,分为L1/L2/L3缓存。- CPU访问缓存的速度比内存快10-100倍,如循环变量因驻留缓存而加速运算。
缓冲区(Buffer)-内存中用于暂存IO数据的区域(如磁盘写入前先存缓冲区,攒够一定量再批量写入)。- 减少磁盘IO次数,提升写入效率(如数据库事务提交前先写入日志缓冲区)。
RAID独立磁盘冗余阵列(Redundant Array of Independent Disks)通过多块磁盘组合提供数据冗余和性能提升,常见级别:
- RAID0(条带化,无冗余)
- RAID1(镜像,高冗余)
- RAID5(奇偶校验,兼顾性能与冗余)
- 服务器用RAID5存储数据,确保一块磁盘损坏时数据不丢失,同时提升读写速度。

关键概念对比

对比项说明
缓存 vs 缓冲区- 缓存:加速数据读取(读优化),如CPU缓存存储内存数据副本。
- 缓冲区:暂存待写入数据(写优化),如打印数据先存缓冲区再批量发送到打印机。
并发 vs 并行- 并发:逻辑上同时执行(单核CPU通过调度实现)。
- 并行:物理上同时执行(多核CPU或多处理器)。
死锁 vs 饥饿- 死锁:循环等待资源,所有进程阻塞。
- 饥饿:低优先级进程长期无法获得资源(如高优先级进程持续抢占CPU)。
信号 vs 信号量- 信号:简单异步通知(如终止进程),不携带数据。
- 信号量:复杂同步机制,通过计数器控制资源访问。

Unix 常用编程接口速查表

分类接口名称功能描述典型用法示例头文件
进程管理fork()创建子进程,返回两次(父进程返回子进程 PID,子进程返回 0)pid_t pid = fork();
if (pid == 0) { /* 子进程逻辑 / } else { / 父进程逻辑 */ }
#include <unistd.h>
execve()在子进程中替换当前进程的执行程序(常与 fork 配合)char *argv[] = {"/bin/ls", NULL};
execve("/bin/ls", argv, environ);
#include <unistd.h>
wait()阻塞等待子进程结束,获取其退出状态int status;
wait(&status);
#include <sys/wait.h>
exit()终止当前进程(正常退出)exit(EXIT_SUCCESS); /* 成功退出 */#include <stdlib.h>
文件操作open()打开或创建文件,返回文件描述符(FD)`int fd = open(“file.txt”, O_RDWRO_CREAT, 0644);`
read()从文件描述符读取数据char buf[1024];
ssize_t n = read(fd, buf, sizeof(buf));
#include <unistd.h>
write()向文件描述符写入数据write(fd, "hello", 5);#include <unistd.h>
close()关闭文件描述符close(fd);#include <unistd.h>
lseek()调整文件读写位置(偏移量)off_t offset = lseek(fd, 0, SEEK_END); /* 获取文件大小 */#include <unistd.h>
多线程pthread_create()创建线程(POSIX 线程接口)pthread_t tid;
pthread_create(&tid, NULL, thread_func, NULL);
#include <pthread.h>
pthread_join()阻塞等待线程结束pthread_join(tid, NULL);#include <pthread.h>
网络通信socket()创建网络套接字(IPv4/IPv6,TCP/UDP)int sock = socket(AF_INET, SOCK_STREAM, 0); /* TCP 套接字 */#include <sys/socket.h>
bind()将套接字绑定到本地地址和端口struct sockaddr_in addr;
bind(sock, (struct sockaddr*)&addr, sizeof(addr));
#include <sys/socket.h>
listen()标记套接字为被动监听状态(TCP 服务器)listen(sock, 5); /* 最大连接数 5 */#include <sys/socket.h>
accept()接受客户端连接(TCP 服务器)int conn_fd = accept(sock, NULL, NULL);#include <sys/socket.h>
connect()发起网络连接(客户端)connect(sock, (struct sockaddr*)&addr, sizeof(addr));#include <sys/socket.h>
字符串处理strcpy()复制字符串(需注意缓冲区溢出风险)char dest[20];
strcpy(dest, "source");
#include <string.h>
strlen()获取字符串长度(不包含空字符)size_t len = strlen("hello");#include <string.h>
内存管理malloc()动态分配内存(需手动 free 释放)int *ptr = (int*)malloc(sizeof(int));#include <stdlib.h>
free()释放动态分配的内存free(ptr);#include <stdlib.h>
信号处理signal()注册信号处理函数(如处理 Ctrl+C)signal(SIGINT, sig_handler); /* 处理中断信号 */#include <signal.h>
目录操作opendir()打开目录,返回目录流指针DIR *dir = opendir("/etc");#include <dirent.h>
readdir()读取目录下的文件条目struct dirent *entry;
while ((entry = readdir(dir)) != NULL) { ... }
#include <dirent.h>

关键说明

  1. 系统调用 vs 库函数

    • 部分接口(如 openread)是 系统调用,直接与内核交互;
    • 部分(如 strcpymalloc)是 C 标准库函数,可能基于系统调用实现。
  2. 错误处理
    大多数接口返回 -1 表示错误(如 openread),可通过 errno 变量获取具体错误码(需包含 #include <errno.h>)。

  3. POSIX 兼容性
    上述接口均属于 POSIX 标准定义,可在主流 Unix/Linux 系统(如 Linux、macOS、FreeBSD)上通用。

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

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

相关文章

opencv(双线性插值原理)

双线性插值是一种图像缩放、旋转或平移时进行像素值估计的插值方法。当需要对图像进行变换时&#xff0c;特别是尺寸变化时&#xff0c;原始图像的某些像素坐标可能不再是新图像中的整数位置&#xff0c;这时就需要使用插值算法来确定这些非整数坐标的像素值。 双线性插值的工…

echarts模板化开发,简易版配置大屏组件-根据配置文件输出图形和模板(vue2+echarts5.0)

实现结果 项目结构 根据我的目录和代码 复制到项目中 echartsTemplate-echarts图形 pie实例 <template><div :id"echartsId"></div> </template> <script> export default {name: ,components: {},mixins: [],props: [echartsId,…

Qt项目——Tcp网络调试助手服务端与客户端

目录 前言结果预览工程文件源代码一、开发流程二、Tcp协议三、Socket四、Tcp服务器的关键流程五、Tcp客户端的关键流程六、Tcp服务端核心代码七、客户端核心代码总结 前言 这期要运用到计算机网络的知识&#xff0c;要搞清楚Tcp协议&#xff0c;学习QTcpServer &#xff0c;学…

4.21 从0开始配置spark-local模式

首先准备好安装包 然后使用命令解压 使用source /etc/profile命令让环境变量生效 输入命令 spark-submit --class org.apache.spark.examples.SparkPi --master local[2] /opt/module/spark-local/examples/jars/spark-examples_2.12-3.1.1.jar 10 即在spark运行了第一个程序…

chili3d调试笔记3 加入c++ 大模型对话方法 cmakelists精读

加入 #include <emscripten/bind.h> #include <emscripten/val.h> #include <nlohmann/json.hpp> 怎么加包 函数直接用emscripten::function&#xff0c;如&#xff1a; emscripten::function("send_to_llm", &send_to_llm); set (CMAKE_C…

go语言八股文

1.go语言的接口是怎么实现 接口&#xff08;interface&#xff09;是一种类型&#xff0c;它定义了一组方法的集合。任何类型只要实现了接口中定义的所有方法&#xff0c;就被认为实现了该接口。 代码的实现 package mainimport "fmt"// 定义接口 type Shape inte…

基于 DeepSeek大模型 开发AI应用的理论和实战书籍推荐,涵盖基础理论、模型架构、实战技巧及对比分析,并附表格总结

以下是基于 DeepSeek大模型 开发AI应用的理论和实战书籍推荐&#xff0c;涵盖基础理论、模型架构、实战技巧及对比分析&#xff0c;并附表格总结&#xff1a; 1. 推荐书籍及内容说明 (1) 《深度学习》&#xff08;Deep Learning&#xff09; 作者&#xff1a;Ian Goodfellow…

从数字化到智能化,百度 SRE 数智免疫系统的演进和实践

1. 为什么 SRE 需要数智免疫系统&#xff1f; 2022 年 10 月&#xff0c;在 Gartner 公布的 2023 年十大战略技术趋势中提到了「数字免疫系统」的概念&#xff0c;旨在通过结合数据驱动的一系列手段来提高系统的弹性和稳定性。 在过去 2 年的时间里&#xff0c;百度基于该…

ArcGIS及其组件抛出 -- “Sorry, this application cannot run under a Virtual Machine.“

产生背景&#xff1a; 使用的是“破解版本”或“被套壳过”的非官方 ArcGIS 版本 破解版本作者为了防止&#xff1a; 被研究破解方式 被自动化抓包/提权/逆向 被企业环境中部署多机使用 通常会加入**“虚拟化环境检测阻断运行”机制** 原因解释&#xff1a; 说明你当前运…

进阶篇 第 5 篇:现代预测方法 - Prophet 与机器学习特征工程

进阶篇 第 5 篇&#xff1a;现代预测方法 - Prophet 与机器学习特征工程 (图片来源: ThisIsEngineering RAEng on Pexels) 在前几篇中&#xff0c;我们深入研究了经典的时间序列统计模型&#xff0c;如 ETS 和强大的 SARIMA 家族。它们在理论上成熟且应用广泛&#xff0c;但有…

影刀填写输入框(web) 时出错: Can not convert Array to String

环境&#xff1a; 影刀5.26.24 Win10专业版 问题描述&#xff1a; [错误来源]行12: 填写输入框(web) 执行 填写输入框(web) 时出错: Can not convert Array to String. 解决方案&#xff1a; 1. 检查变量内容 在填写输入框之前&#xff0c;打印BT和NR变量的值&#xff…

词语关系图谱模型

参数配置说明 sentences, # 分词后的语料&#xff08;列表嵌套列表&#xff09; vector_size100, # 每个词的向量维度 window5, # 词与上下文之间的最大距离&#xff08;滑动窗口大小&#xff09; min_count5, # 忽略出现次数小于5的…

HTTP的请求消息Request和响应消息Response

一&#xff1a;介绍 &#xff08;1&#xff09;定义 service方法里的两个参数 &#xff08;2)过程 Request:获取请求数据 浏览器发送http请求数据&#xff08;字符串&#xff09;&#xff0c;字符串被tomcat解析&#xff0c;解析后tomcat会将请求数据放入request对象 Response:…

C++异步操作 - future async package_task promise

异步 异步编程是一种程序设计范式&#xff0c;​​允许任务在等待耗时操作&#xff08;如I/O、网络请求&#xff09;时暂停执行&#xff0c;转而处理其他任务&#xff0c;待操作完成后自动恢复​​。其核心目标是​​避免阻塞主线程​​&#xff0c;提升程序的并发性和响应速度…

数据结构——栈以及相应的操作

栈(Stack) 在维基百科中是这样定义的&#xff1a; 堆栈(stack) 又称为栈或堆叠&#xff0c;是计算机科学中的一种抽象资料类型&#xff0c;只允许在有序的线性资料集合中的一端&#xff08;称为堆栈顶端&#xff0c;top&#xff09;进行加入数据&#xff08;push&#xff09;和…

如何应对政策变化导致的项目风险

应对政策变化导致的项目风险&#xff0c;核心在于&#xff1a;加强政策研判机制、建立动态应对流程、构建合规应急预案、强化跨部门联动、提升项目柔性与调整能力。其中&#xff0c;加强政策研判机制 是所有防范工作中的“前哨哨兵”&#xff0c;可以让项目团队在政策风向转变之…

ASP.Net Web Api如何更改URL

1.找到appsettings.json 修改如下&#xff1a; 主要为urls的修改填本机私有地址即可 {"Logging": {"LogLevel": {"Default": "Information","Microsoft.AspNetCore": "Warning"}},"AllowedHosts": &q…

【HTTPS协议原理】数据加密、如何防止中间人攻击、证书和签名、HTTPS完整工作流程

⭐️个人主页&#xff1a;小羊 ⭐️所属专栏&#xff1a;Linux网络 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 数据加密常见的加密方式数据摘要方案一&#xff1a;仅使用对称加密方案二&#xff1a;仅使用非对称加密方案三&#xff1a;双…

Java中链表的深入了解及实现

一、链表 1.链表的概念 1.1链表是⼀种物理存储结构上⾮连续存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的引⽤链接次序实现的 实际中链表的结构⾮常多样&#xff0c;以下情况组合起来就有8种链表结构&#xff1a; 2.链表的实现 1.⽆头单向⾮循环链表实现 链表中的…

植物大战僵尸杂交版v3.6最新版本(附下载链接)

B站游戏作者潜艇伟伟迷于4月19日更新了植物大战僵尸杂交版3.6版本&#xff01;&#xff01;&#xff01;&#xff0c;有b站账户的记得要给作者三连关注一下呀&#xff01; 不多废话下载链接放上&#xff1a; 夸克网盘链接&#xff1a;&#xff1a;https://pan.quark.cn/s/1af9b…