当前位置: 首页 > news >正文

计算机系统---CPU的进程与线程处理

在计算机系统中,CPU作为“运算核心”,其核心工作并非直接执行“软件”,而是通过进程与线程这两个抽象层,实现对海量任务的有序调度、资源隔离与高效并发。理解CPU如何处理进程与线程,本质是理解操作系统如何“管理任务”与“分配算力”——这一过程覆盖了资源定义、状态流转、调度算法、同步互斥、通信机制等多个维度,是计算机体系的核心知识体系。

一、基础概念:进程与线程的定义与本质区别

要理解CPU的处理逻辑,首先需明确“进程”与“线程”的核心定位——二者是操作系统对“任务”的不同粒度抽象,承担着“资源分配”与“调度执行”的不同角色。

1. 进程(Process):资源分配的基本单位

进程是程序的一次运行实例,是操作系统为其分配内存、CPU、文件句柄等资源的“最小单元”。当你双击“浏览器”图标时,操作系统会:

  • 为浏览器分配独立的地址空间(如4GB虚拟内存,与其他进程隔离,避免数据篡改);
  • 加载程序代码与初始化数据到内存;
  • 创建一个“进程控制块(PCB,Process Control Block)”——这是进程的“身份证”,存储进程ID、状态(就绪/运行/阻塞)、寄存器值、内存地址范围、打开的文件列表等核心信息;
  • 将进程加入“就绪队列”,等待CPU调度。

简单说,进程是“资源的容器”——每个进程都拥有独立的资源集合,确保不同程序运行时互不干扰(例如,浏览器进程崩溃不会导致微信进程关闭)。

2. 线程(Thread):CPU调度的基本单位

线程是进程内的执行流,是CPU实际“调度执行”的最小单元。一个进程至少包含一个线程(称为“主线程”),也可创建多个线程(如浏览器的“渲染线程”“JS执行线程”“网络请求线程”)。

线程与进程的核心区别在于资源共享

  • 线程不拥有独立资源,而是共享所属进程的所有资源(如内存地址空间、文件句柄、网络连接);
  • 线程仅拥有自身的“私有数据”:1.线程ID(TID)、2.程序计数器(PC,记录下一条要执行的指令地址)、3.寄存器组(存储当前计算的临时数据)、4.栈空间(存储函数调用栈,避免线程间栈数据冲突)。

举个通俗例子:如果进程是“一家公司”,那么资源(资金、办公场地、设备)归公司所有;线程就是“公司里的员工”,共享公司资源,各自执行不同任务(如销售、财务、研发),且员工间沟通成本远低于不同公司间的合作成本。

3. 进程与线程的核心差异(表格对比)

对比维度进程(Process)线程(Thread)
资源分配单位操作系统资源分配的最小单元不分配资源,共享所属进程资源
CPU调度单位不直接被调度(需通过线程)CPU调度的最小单元
地址空间独立(每个进程有专属虚拟地址空间)共享(与所属进程的地址空间完全一致)
上下文切换开销大(需切换地址空间、资源列表等)小(仅需切换PC、寄存器、栈,资源不变)
通信成本高(需通过IPC机制,如管道、共享内存)低(直接读写共享内存,需同步机制)
稳定性高(一个进程崩溃不影响其他进程)低(一个线程崩溃可能导致整个进程崩溃)

二、进程与线程的状态流转:CPU调度的“任务生命周期”

CPU处理进程/线程的核心逻辑,围绕“状态转换”展开——进程并非始终处于“运行”状态,而是在不同状态间切换,操作系统通过状态管理实现对任务的有序调度。

1. 进程的五大核心状态(经典模型)

所有进程的生命周期都围绕以下5种状态流转,CPU仅会调度“就绪态”进程:

  • 新建态(New):进程刚被创建(如双击软件),操作系统正在为其分配资源、初始化PCB,尚未加入就绪队列;
  • 就绪态(Ready):进程已具备运行条件(资源分配完成),等待CPU空闲,加入“就绪队列”;
  • 运行态(Running):进程被CPU调度,正在执行指令(此时CPU的寄存器、PC均指向该进程的上下文);
  • 阻塞态(Blocked):进程因等待资源/事件(如等待磁盘读写完成、等待网络数据、等待键盘输入)而暂停,主动放弃CPU,加入“阻塞队列”(即使CPU空闲,也无法调度阻塞态进程);
  • 终止态(Terminated):进程完成任务或异常退出(如点击关闭按钮、崩溃),操作系统回收其资源(内存、文件句柄),删除PCB。

2. 状态转换的核心触发条件

状态流转是操作系统与CPU协同工作的体现,关键转换路径包括:

  1. 新建态 → 就绪态:进程初始化完成,资源分配完毕;
  2. 就绪态 → 运行态:CPU调度器从就绪队列中选择一个进程(按调度算法),将其上下文加载到CPU;
  3. 运行态 → 就绪态:进程用完“时间片”(如10ms),或有更高优先级进程进入就绪队列,操作系统剥夺当前CPU使用权,保存其上下文,放回就绪队列;
  4. 运行态 → 阻塞态:进程发起“阻塞请求”(如调用read()函数读取文件),主动放弃CPU,等待事件完成;
  5. 阻塞态 → 就绪态:进程等待的事件完成(如文件读取完毕),操作系统将其从阻塞队列移回就绪队列;
  6. 运行态 → 终止态:进程执行完exit()指令,或因错误(如内存访问越界)被操作系统终止。

3. 线程的状态与进程的差异

线程的状态模型与进程基本一致(新建、就绪、运行、阻塞、终止),但有一个关键区别:线程的阻塞不会导致进程阻塞。例如,浏览器的“网络请求线程”因等待数据进入阻塞态时,“渲染线程”仍可继续运行(显示页面),整个浏览器进程保持活跃。

三、线程的实现模型:CPU如何“感知”线程

线程并非硬件直接支持的概念,而是操作系统通过软件层抽象实现的。不同的实现模型,直接决定了CPU能否利用多核、线程调度的开销大小,核心分为三类:

1. 用户级线程(ULT,User-level threads):操作系统“看不见”的线程

  • 实现逻辑:线程的创建、调度、状态管理均由“用户态库”(如POSIX的pthread库)实现,操作系统仅感知进程,不感知线程;
  • 映射关系:多对一(多个用户级线程对应1个内核级线程,内核级线程是操作系统与CPU交互的最小单元);
  • 优缺点
    • 优点:线程切换在用户态完成(无需陷入内核),开销极小;可在不支持线程的操作系统上运行;
    • 缺点:无法利用多核CPU(一个进程的所有线程只能在一个CPU核心上运行,因内核仅分配一个内核线程);若一个线程阻塞(如等待IO),整个进程的所有线程都会被阻塞(内核认为进程阻塞)。
  • 应用场景:早期UNIX系统、轻量级并发场景(如脚本语言的线程)。

2. 内核级线程(KLT,Kernel-level threads):操作系统“直接管理”的线程

  • 实现逻辑:线程的创建、调度、状态管理均由操作系统内核实现,每个线程对应一个“线程控制块(TCB)”,内核通过TCB调度线程;
  • 映射关系:一对一(1个用户级线程对应1个内核级线程);
  • 优缺点
    • 优点:可利用多核CPU(多个线程可被调度到不同核心);一个线程阻塞时,其他线程不受影响(内核仅标记该线程阻塞);
    • 缺点:线程切换需“陷入内核”(保存/加载TCB),开销较大;线程数量受限于内核资源(TCB占用内存,过多线程会消耗内核资源)。
  • 应用场景:Windows、Linux(2.6版本后)、现代操作系统的主流模型。

3. 混合级线程(HLT,Mixed-level threads):平衡开销与多核利用

  • 实现逻辑:结合用户级线程与内核级线程,由用户态库管理“用户级线程池”,内核管理“内核级线程池”;
  • 映射关系:多对多(多个用户级线程对应多个内核级线程,数量可动态调整);
  • 优缺点
    • 优点:兼顾低开销(用户态切换)与多核利用(内核级线程调度到多核心);线程数量灵活(用户级线程可远多于内核级线程);
    • 缺点:实现复杂(需用户态库与内核协同);
  • 应用场景:Solaris系统、Java虚拟机(JVM)的线程模型(如HotSpot VM在Linux上的实现)。

四、CPU调度机制:如何选择“下一个要运行的任务”

CPU的核心能力是“并发执行多任务”,但单个CPU核心同一时间只能执行一个线程——操作系统通过“调度算法”,实现“多任务并发”的错觉。调度机制分为三级调度,其中“短程调度”直接决定CPU执行哪个任务。

1. 三级调度:从“任务入内存”到“CPU执行”的全流程

调度级别别称核心作用调度对象频率
长程调度作业调度选择“外存中的作业”加载到内存,创建进程作业(如用户提交的任务)低(分钟级)
中程调度内存调度当内存不足时,将“部分进程挂起”(移到外存),释放内存;内存充足时“激活挂起进程”进程中(秒级)
短程调度CPU调度从“就绪队列”选择线程/进程,分配CPU使用权就绪态线程/进程高(毫秒级)

核心重点:短程调度——这是CPU与操作系统交互最频繁的环节,直接影响系统的响应速度与吞吐量。

2. 短程调度的核心目标

不同场景下,调度算法的优化目标不同,需在以下目标间权衡:

  • CPU利用率:让CPU尽可能 busy(避免空闲);
  • 吞吐量:单位时间内完成的任务数(如服务器场景优先);
  • 响应时间:从用户发起请求到得到响应的时间(如桌面系统优先);
  • 周转时间:任务从“进入就绪态”到“执行完成”的总时间(包括等待时间+运行时间);
  • 公平性:避免某个任务长期得不到CPU(即“饥饿”问题)。

3. 经典调度算法:从理论到实际应用

(1)先来先服务(FCFS, First-Come, First-Served):最简单的“排队算法”
  • 逻辑:按进程进入就绪队列的顺序调度,先到先执行,直到进程完成或阻塞;
  • 例子:就绪队列依次进入A(运行时间10ms)、B(1ms)、C(1ms),总周转时间=10 + (10+1) + (10+1+1)=33ms;
  • 优缺点:实现简单、公平;但“短作业会被长作业阻塞”(如B、C需等A执行完),吞吐量低。
  • 应用场景:早期批处理系统(无交互需求)。
(2)短作业优先(SJF, Shortest Job First):“短任务优先”的优化
  • 逻辑:选择“预计运行时间最短”的就绪进程先执行,分两种:
    • 非抢占式:一旦进程开始运行,直到完成或阻塞才放弃CPU;
    • 抢占式(也叫“最短剩余时间优先SRTF”):若新进入就绪队列的进程运行时间短于当前进程的剩余时间,立即剥夺CPU;
  • 例子:同上队列A(10)、B(1)、C(1),非抢占式总周转时间=1 + (1+1) + (1+1+10)=15ms(远优于FCFS);
  • 优缺点:平均周转时间最短;但“长作业会饥饿”(若持续有短作业进入,长作业永远得不到CPU);无法准确预测运行时间。
  • 应用场景:可预测任务运行时间的场景(如批处理系统)。
(3)高响应比优先(HRRN):解决SJF的饥饿问题
  • 逻辑:通过“响应比”动态选择进程,响应比 =(等待时间+预计运行时间)/预计运行时间;等待时间越长,响应比越高,即使是长作业,等待时间足够长后也会被调度;
  • 例子:就绪队列A(10)、B(1)、C(1),初始响应比A=1(0+10/10)、B=1(0+1/1)、C=1(0+1/1),随机选B执行;B完成后,A等待时间=1,响应比=(1+10)/10=1.1,C响应比=(1+1)/1=2,选C执行;C完成后,A响应比=(2+10)/10=1.2,选A执行;总周转时间=1 + (1+1) + (2+10)=15ms(同SJF),且无饥饿;
  • 优缺点:兼顾公平与效率,解决饥饿;但需实时计算响应比,开销略高。
  • 应用场景:批处理与交互混合系统。
(4)时间片轮转(Round Robin, RR):交互系统的“基础算法”
  • 逻辑:为每个就绪进程分配固定“时间片”(如10ms),进程用完时间片后,无论是否执行完,都放回就绪队列末尾,调度下一个进程;
  • 关键参数:时间片大小——太小会导致“上下文切换频繁”(开销高),太大则响应时间长(接近FCFS);通常时间片设为“10-100ms”(匹配人类感知的响应速度);
  • 例子:就绪队列A(10)、B(1)、C(1),时间片=2ms:A运行2ms→B运行1ms(完成)→C运行1ms(完成)→A运行2ms→A运行2ms→A运行2ms→A运行2ms(完成);总周转时间=10 + (2+1) + (2+1+1)=17ms;
  • 优缺点:响应时间短(适合桌面系统,如Windows、macOS);公平性好;但平均周转时间长,上下文切换开销高。
  • 应用场景:分时系统(多用户交互)、桌面操作系统。
(5)多级反馈队列(Multileved Feedback Queue,MLFQ):实际系统的“主流算法”

MLFQ是“时间片轮转”与“优先级调度”的结合,被Linux(早期O(1)调度器)、Windows XP等系统采用,核心逻辑如下:

  1. 多队列设计:设置多个优先级队列(如Q0-Q7,Q0优先级最高,Q7最低);
  2. 时间片规则:优先级越高,时间片越小(如Q0时间片=10ms,Q1=20ms,每低一级时间片翻倍);
  3. 调度规则
    • 仅调度最高优先级队列中的进程(若Q0有进程,不调度Q1及以下);
    • 同优先级队列内按RR调度;
    • 进程用完时间片后,优先级降低一级(如Q0→Q1),放入对应队列;
    • 进程等待时间过长(如Q7的进程等待500ms),优先级提升一级(避免饥饿);
    • 新创建的进程放入最高优先级队列(Q0),确保快速响应(如用户点击打开软件);
  • 优点:兼顾响应时间(高优先级短时间片)、吞吐量(低优先级长时间片)与公平性(避免饥饿),适配复杂场景;
  • 应用场景:通用操作系统(桌面、服务器)。
(6)Linux CFS调度器:现代系统的“公平调度”

Linux 2.6.23后采用“完全公平调度器(CFS)”,摒弃传统“优先级队列”,核心思想是“让每个线程获得公平的CPU时间”:

  • 虚拟运行时间(vruntime):为每个线程维护“虚拟运行时间”,计算公式=实际运行时间 × (1024/线程权重);权重由线程优先级决定(优先级越高,权重越大,vruntime增长越慢);
  • 调度逻辑:CPU始终选择“vruntime最小”的线程执行,确保权重高的线程(高优先级)获得更多CPU时间;
  • 优点:无固定时间片,动态调整执行时长,公平性与效率平衡,适配多核CPU。

五、进程与线程的同步与互斥:避免“资源争抢”的混乱

当多个线程/进程共享资源(如内存中的全局变量、磁盘文件)时,会出现“竞态条件”(Race Condition)——例如,两个线程同时修改“计数器”(初始值=0),均执行“count=count+1”,最终结果可能是1而非2(因指令执行被打断)。为解决这一问题,需通过“同步与互斥”机制保证资源访问的有序性。

1. 核心概念

  • 临界区(Critical Section):访问共享资源的代码段(如“count=count+1”),需确保“同一时间只有一个线程/进程进入”;
  • 互斥(Mutual Exclusion):多个线程/进程不能同时进入临界区;
  • 同步(Synchronization):多个线程/进程按约定顺序执行(如“线程A完成后,线程B才能执行”)。

2. 互斥机制的实现

(1)硬件方法:底层指令保障
  • 中断禁用:线程进入临界区前禁用CPU中断(避免被调度打断),退出后启用中断;优点简单,缺点禁用中断期间CPU无法响应其他任务(适合单核心,多核无效);
  • 测试并设置(TS指令):一条原子指令(不可被打断),功能是“读取内存值→判断是否为0→若为0则设为1并返回true,否则返回false”;线程通过TS指令获取“锁”,获取成功才进入临界区;
  • 交换(XCHG指令):原子交换两个内存值,逻辑与TS类似,通过交换“锁变量”与“本地变量”实现互斥。
(2)软件方法:信号量与管程
  • 信号量(Semaphore):由荷兰科学家Dijkstra提出,是最经典的同步原语,定义为一个非负整数S,支持两种原子操作:
    • P操作(Wait):S=S-1;若S<0,线程阻塞,加入信号量的等待队列;
    • V操作(Signal):S=S+1;若S≤0,唤醒等待队列中的一个线程;
    • 应用:二进制信号量(S=0或1)用于互斥(初始化S=1,临界区前P操作,后V操作);计数信号量(S≥0)用于同步(如控制同时访问资源的线程数)。
  • 管程(Monitor):将“共享资源+临界区+同步操作”封装成一个“对象”,确保只有管程内的函数能访问共享资源,且同一时间只有一个线程执行管程内的函数;管程内置“条件变量”(如wait()signal()),实现线程间同步;优点是安全性高(避免信号量使用不当导致的死锁),被Java、C#等语言支持(如Java的synchronized关键字本质是管程)。

3. 死锁:同步机制的“陷阱”

死锁是多个线程/进程因“互相等待对方释放资源”而永久阻塞的状态,需满足四大必要条件:

  1. 互斥条件:资源只能被一个线程/进程占用;
  2. 持有并等待条件:线程/进程持有部分资源,同时等待其他资源;
  3. 不可剥夺条件:资源只能由持有者主动释放,不能被强制剥夺;
  4. 循环等待条件:多个线程/进程形成“资源等待环”(如A等B的资源,B等A的资源)。

死锁的解决策略

  • 预防:破坏四大条件之一(如“资源有序分配”破坏循环等待,“一次性分配所有资源”破坏持有并等待);
  • 避免:动态判断是否会产生死锁,如“银行家算法”(模拟分配资源,若分配后系统处于“安全状态”则允许分配);
  • 检测与解除:通过“资源分配图”检测死锁,解除方法包括“剥夺资源”“终止进程”(如Linux的OOM Killer会终止占用内存多的进程,解除内存资源死锁)。

六、进程与线程的通信机制:如何“交换数据”

进程间因地址空间独立,需通过操作系统提供的“进程间通信(IPC,Inter Process Communication)”机制交换数据;线程间因共享地址空间,通信更简单,但需同步机制保障安全。

1. 进程间通信(IPC,Inter Process Communication)的核心方式

IPC机制实现逻辑优缺点应用场景
管道(Pipe)内核维护的“字节流缓冲区”,分为匿名管道(父子进程间)与命名管道(任意进程间),半双工(需双向通信需两个管道)优点简单;缺点无消息边界,只能传输字节流命令行重定向(如`ls
消息队列内核维护的“消息链表”,进程按“消息类型”发送/接收消息,有消息边界优点支持结构化数据;缺点消息大小有限制进程间异步通信(如服务器通知客户端)
共享内存内核分配一块“共享内存区域”,多个进程将其映射到自身地址空间,直接读写内存优点速度最快(无需内核拷贝);缺点需同步机制高频数据传输(如数据库、游戏)
信号量用于同步与互斥,非数据传输,常与共享内存配合使用优点轻量;缺点不能传输数据共享资源的访问控制
信号(Signal)内核向进程发送的“异步通知”(如Ctrl+C发送SIGINT信号),进程可自定义处理函数优点实时性高;缺点只能传递信号编号异常处理(如进程崩溃通知)
套接字(Socket)跨主机/本地进程通信的网络协议接口,支持TCP/UDP优点跨网络;缺点开销大网络通信(如浏览器与服务器)

2. 线程间通信(ITC,Inter Thread Communication)的核心方式

  • 共享内存:直接读写进程的全局变量、静态变量,需通过synchronizedmutex等同步机制避免竞态条件;
  • 消息传递:通过线程安全的队列(如Java的ConcurrentLinkedQueue)传递消息,避免直接共享数据;
  • 条件变量:管程内置的同步机制,用于线程间“等待-通知”(如线程A等待某个条件满足,线程B满足条件后通知A)。

七、总结:CPU处理进程与线程的“全流程闭环”

当用户双击“浏览器”图标时,CPU与操作系统的协同流程如下:

  1. 进程创建:操作系统为浏览器分配内存、创建PCB,初始化主线程(创建TCB),将进程加入就绪队列;
  2. CPU调度:短程调度器(如Linux CFS)选择该进程的主线程,加载其上下文(PC、寄存器)到CPU,主线程进入运行态,执行浏览器初始化代码;
  3. 线程创建:浏览器主线程创建“渲染线程”“JS线程”“网络线程”,共享浏览器进程的内存与文件资源;
  4. 状态流转:网络线程发起HTTP请求,进入阻塞态(等待数据),CPU调度渲染线程运行(绘制页面);网络数据到达后,网络线程从阻塞态转为就绪态,等待CPU调度;
  5. 同步与通信:JS线程修改DOM时,通过同步机制(如锁)通知渲染线程更新页面,避免资源争抢;
  6. 进程终止:用户点击关闭按钮,浏览器进程的所有线程执行终止逻辑,操作系统回收资源(内存、文件句柄),删除PCB/TCB,进程进入终止态。

从“进程创建”到“终止”,CPU的核心工作是“按调度算法分配算力”,操作系统的核心工作是“管理资源、维护状态、保障同步”——二者协同实现了“多任务并发”的计算机核心能力,也是现代操作系统与CPU设计的底层逻辑。

http://www.dtcms.com/a/482991.html

相关文章:

  • cv_bridge和openCV不兼容问题
  • json转excel python pd
  • 上海网站建设排名公司哪家好天蝎网站建设公司
  • 进入网络管理的网站不想用原来的网站模板了就用小偷工具采集了一个可是怎么替换
  • 西安注册公司在哪个网站系统哈尔滨模板网站
  • android 开机启动 无线调试
  • Polaris Officev9.9.12全功能解锁版
  • 云信im在Android的使用
  • 王道数据结构应用题强化表3.1.1-3.1.6
  • JDK 1.8 自动化脚本安装方案
  • 网站备案不通过怎么解决小米网站建设案例
  • 网路原理:UDP协议
  • 什么是区块链主机托管?为何要使用主机托管?
  • R语言空间数据分析实战:机器学习预测、尺度转换与地统计建模
  • 数据结构系列之堆
  • MySQL索引原理
  • 扁平化网站源码云服务器最便宜
  • 一个网站的成功深圳市深企在线技术开发有限公司
  • Python学习-----小游戏之人生重开模拟器(普通版)
  • 上海网站建设的网html网站系统
  • 理解AUROC,AP,F1-scroe,PRO
  • php做网站安全性wordpress 网银
  • 教程上新|重新定义下一代 OCR:IBM 最新开源 Granite-docling-258M,实现端到端的「结构+内容」统一理解
  • 网络原理 -- HTTP
  • 县级门户网站建设的报告网页游戏网站排名
  • 快速创建无线AP热点
  • CSS级联层样式权重和优先级
  • 免费搭建私人网站修改wordpress后台文字
  • 站内推广的方法网络整合营销传播
  • 国际网站建设的目的网站建设预算知乎