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

线程与协程

1. 线程与协程

1.1. “函数调用级别”的切换、上下文切换

1. 函数调用级别的切换

“函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。

举例说明:

当你在程序中写一个函数调用:

funcA()

然后 funcA 执行完后返回,CPU 不需要保存太多额外的信息,只是:

  • 压栈/出栈(保存调用点、局部变量等)
  • 跳转指令地址(比如函数返回到调用者)

这种切换就是非常轻量级的,发生在用户态,速度快、成本低。

协程之间的切换通常只涉及「函数调用级别」的保存和恢复,例如程序计数器(PC)、栈指针(SP)等。

 

2. 上下文切换

上下文切换是操作系统在多任务之间切换时保存和恢复执行状态的过程,通常发生在线程/进程之间。

典型上下文包含:

  • CPU 寄存器(程序计数器 PC、堆栈指针 SP、通用寄存器)
  • 内存映射 / 虚拟地址空间(尤其是进程间)
  • 线程/进程控制块(如 PCB/TCB)

上下文切换的代价大:

  1. 保存当前线程的寄存器、状态
  2. 切换到内核态(Trap)
  3. 操作系统调度另一个线程/进程
  4. 恢复新线程的上下文
  5. 切换回用户态,继续执行

这会消耗 CPU 时间、内存带宽和系统资源,频繁切换会严重影响性能。

对比总结

项目

协程切换(函数调用级别)

线程/进程切换(上下文切换)

切换方式

用户态,像调用函数一样

操作系统调度,涉及内核态

状态保存/恢复

少量(程序计数器、栈指针)

全部寄存器、堆栈、内存映射等

是否切内核态

是(陷入内核)

开销

极小

较大(系统调用 + 状态切换)

性能影响

轻微

明显(频繁切换容易降低性能)

1.2. 线程(Thread)

概念:

线程是操作系统调度的最小单位,一个线程对应一条执行路径。多个线程可以并发执行任务,从而提升程序的响应性和性能。

特点:

  • 每个线程有自己的堆栈空间和程序计数器
  • 多个线程共享进程内的资源(如内存、文件);
  • 线程之间切换需要操作系统调度,代价较高(上下文切换)
  • 在多核 CPU 下,线程可以实现真正的并行(每核跑一个线程);
  • 适合 I/O 密集和 CPU 密集场景,但创建和调度较重。

举例(Python 中):

import threadingdef task():print("线程正在运行")t = threading.Thread(target=task)
t.start()

1.3. 协程(Coroutine)

概念:

协程是一种用户态的轻量级线程,又叫微线程,不由操作系统调度,而是由程序自己控制何时挂起、何时恢复

特点:

  • 本质是单线程内的并发;
  • 用于I/O 密集型任务非常高效(如网络请求、文件读写);
  • 切换开销小,不需要线程上下文切换;
  • 依靠语言或框架调度(如 Python 的 asyncio、Go 的 goroutine);
  • 不适合 CPU 密集任务(因为不能并行运算)。

举例(Python asyncio):

import asyncioasync def task():print("协程正在运行")await asyncio.sleep(1)print("协程运行结束")asyncio.run(task())

1.4. 线程 vs 协程对比总结

对比点

线程(Thread)

协程(Coroutine)

调度方式

操作系统调度

程序主动让出控制权(如 await

是否并发/并行

可实现并发,也可在多核并行

仅并发,不并行(除非多线程协程)

切换开销

大(上下文切换、内核态)

小(用户态)

编程复杂度

中等(注意锁、共享数据)

简单(适合异步 I/O)

适用场景

CPU 密集、I/O 密集

高并发 I/O 密集(如爬虫、Web服务)

Python 举例

threading模块

asyncio, trio, FastAPI

 

什么时候选线程?什么时候选协程?

场景

推荐使用

理由

文件读写、数据库操作

协程(asyncio)

I/O 密集、无需上下文切换、轻量高效

网络服务(如爬虫、Web)

协程(asyncio)

可处理成千上万连接,资源开销低

CPU 密集型计算

多线程 / 多进程

协程无优势,应考虑并行处理能力

简单并发

线程即可

写法直观,不涉及复杂 async/await

 

相关文章:

  • 实现多路视频截图预览之后上传到后台系统
  • 配置Linux的网络为静态IP地址的一些方法
  • HTML 列表、表格、表单 综合案例
  • 如何查看电脑系统的初始安装时间?
  • HTML 列表、表格、表单
  • Linux上并行打包压缩工具
  • 小天互连IM:信创体系下的安全、高效即时通讯新选择
  • 【强化学习】TD-MPC论文解读
  • 方案解读:智慧银行反欺诈大数据管控平台建设方案【附全文阅读】
  • Alpine Linux基本介绍与新手使用指南
  • 雷卯针对易百纳海鸥派海思SD3403 SS928智能视觉AI视觉国产化4K视频开发板防雷防静电方案
  • Java 枚举(Enum)的使用说明
  • tomcat的websocket协议升级。如何从报文交换变成全双工通信?session对象的注册和绑定?
  • 【WebRTC-14】webrtc是如何创建视频的软/硬编码器?
  • Linux ELF文件详解:深入理解可执行文件格式
  • 【模板编程】
  • Java八股文——JVM「类加载篇」
  • websocket实践
  • (41)课60--61高级篇: MySQL体系结构(连接层、服务层、引擎层、存储层)。存储引擎是基于表的,可为不同表指定不同的存储引擎;查询表结构语句 show create table 表名
  • 鹰盾加密器“一机一码”技术全维度剖析:从底层实现到生态防护体系
  • 网站的层级/seo模板建站
  • js做各类图表网站/北京疫情太严重了
  • 苏州网络平台公司/seopeix
  • wordpress 4.9 中文/seo课程培训班
  • 湖南省住房和城乡建设厅网站/什么软件可以排名次
  • 如何给网站做2维码/百度网盘app官方下载