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

Threading 串行VS并发

Threading 串行VS并发

IO 密集型

结果

>>> 串行开始...
下载https://www.baidu.com/成功,状态码为200
下载https://www.sina.com.cn/成功,状态码为200
下载https://www.bilibili.com/成功,状态码为412
耗时:0.42061281204223633
>>> 串行结束...
>>> 并发开始...
下载https://www.baidu.com/成功,状态码为200
下载https://www.sina.com.cn/成功,状态码为200
下载https://www.bilibili.com/成功,状态码为412
耗时:0.1446540355682373
>>> 并发结束...

示例代码

# -*- coding: utf-8 -*-
# I/O密集时多线程例子:一边打印一边下载网页内容 串行VS并发
import requests
import threading
import time# 用几个响应速度较快的真实网页
urls = ["https://www.baidu.com/","https://www.sina.com.cn/","https://www.bilibili.com/"
]def download(url):try:r = requests.get(url, timeout=3)print(f"下载{url}成功,状态码为{r.status_code}")except requests.RequestException as e:print(e)# ===== 串行
def run_serial():print(">>> 串行开始...")start_time = time.time()for url in urls:download(url)end_time = time.time()print(f"耗时:{end_time - start_time}")print(">>> 串行结束...")# ==== 并发(多线程)
def run_threading():print(">>> 并发开始...")start_time = time.time()threads = []for url in urls:t = threading.Thread(target=download, args=(url,))  # target=函数名,args=函数参数(元组)threads.append(t)t.start()  # 线程开始执行for t in threads:t.join()  # join 主线程等待子线程执行完end_time = time.time()print(f"耗时:{end_time - start_time}")print(">>> 并发结束...")if __name__ == '__main__':run_serial()run_threading()

计算密集型

结果

CPU密集任务运行时,并行并不会比串行快多少,达不到加速的效果

>>> 开始串行...
>>> 串行耗时: 73.33004999160767 秒
>>> 开始并发...
>>> 并发耗时: 73.11574292182922 秒

示例代码

# -*- coding: utf-8 -*-
import mathimport requests
import threading
import time# “烧 CPU”的函数:对一大批数字做平方根运算(math.sqrt())N = 500000000def cpu_task():total = 0for i in range(N):total += math.sqrt(i)return total# ==== 串行
def run_serial():print(">>> 开始串行...")start_time = time.time()cpu_task()cpu_task()cpu_task()print(">>> 串行耗时:", time.time() - start_time, "秒")# ==== 并发
def run_threaded():print(">>> 开始并发...")start_time = time.time()threas = []for _ in range(3):t = threading.Thread(target=cpu_task)t.start()threas.append(t)for t in threas:t.join()print(">>> 并发耗时:", time.time() - start_time, "秒")if __name__ == '__main__':run_serial()run_threaded()

总结:多线程的优势与局限

I/O 密集 请求网页、读写文件、等待数据库 ✅ 非常适合
CPU 密集 图像处理、大量计算、加密解密 ❌ 会被 GIL 限制,不如用多进程
少量任务 任务不多,时间也短 ⚠️ 线程切换反而是开销
并发数量极大 上千并发、强隔离 ⚠️ 推荐协程/进程池,线程管理成本高

参考来源

https://zhuanlan.zhihu.com/p/1923003098605033459

http://www.hskmm.com/?act=detail&tid=13315

相关文章:

  • parallel index
  • C语言 第三讲:分支和循环(上) - 教程
  • 中间件专题:Redis
  • 微信个人号开发API/文档/教程
  • 微指令控制器基本原理
  • 一个拒绝过度设计的 .NET 快速开发框架:开箱即用,专注干活
  • 个人微信号二次开发API调用、微信API接口
  • 2025.9.21+7 [未完]
  • VisualStudio-Python-工具指南-全-
  • Gevent和Subprocess问题
  • Ansible自动化运维实战 - 详解
  • 建筑行业能源管理破局:MyEMS 打造商业楼宇 “能耗可视化 + 智能调控” 方案
  • 【数据结构】双向链表 - 指南
  • 告别“能源糊涂账”:MyEMS如何帮企业把能耗数据“算明白、用到位”
  • Windows 离线环境下使用 VS Code 连接容器 Python 环境完整指南(亲测可用)
  • Macos 安装kali报错
  • 完整教程:线程、进程、协程
  • CF913G Power Substring
  • YC大佬分享的 10 个 vibe coding技巧,看完收获巨大
  • ES集群部署-EFK架构实战 - 实践
  • 《BOE解忧实验室》第四季圆满收官 以科技重塑文化生活新范式
  • 洛谷P2261 [CQOI2007] 余数求和
  • arc206 总结
  • 科研必读|提升酿酒酵母表达蛋白产量的关键技术
  • 完整教程:uniapp、devceo华为鸿蒙运行模拟器报错:未开启Hyper-V
  • 浏览器访问页面卡顿刷新页面方法
  • 完整教程:散斑深度相机原理
  • 如何用 Dify 无代码工作流实现 AI 自动化抓取与分析 LinkedIn 招聘数据
  • WSL+共享文件夹搭建zephyr工作环境
  • 如果 Spring Cloud Feign 配置了 OkHttp3 非阻塞 IO(NIO),那么还需要reactor 模型来提高性能吗