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

python高级特性二

python中的GIL(全局解释器锁)
GIL是 CPython 解释器中的一个互斥锁,线程必须先获取 GIL,才能执行 Python 字节码,确保同一时刻只有一个线程执行 Python 字节码。线程执行一定数量的字节码(或遇到 I/O 操作)后,会释放 GIL,让其他线程有机会运行。也就是说在 CPU 密集型任务中,Python 无法真正并行执行多线程代码。GIL导致多线程在单核 CPU 上可以交替执行,但在多核 CPU 上也无法真正并行。
GIL的优点:
✅简化 CPython 实现,避免复杂的线程同步问题。
✅ 提高单线程性能,减少锁竞争开销。
✅ 保护 Python 对象的内存安全。
缺点
❌ 多线程无法真正并行执行(CPU 密集型任务性能受限)。
❌ 多线程在CPU密集型任务中可能比单线程更慢(线程切换开销)。
❌ 限制了 Python 在高并发计算场景的应用(如机器学习)。
CPU 密集型任务:

import threading
import timedef count(n):while n > 0:n -= 1# 单线程
start = time.time()
count(100000000)
print("单线程耗时:", time.time() - start)  # 约 5 秒# 多线程(由于 GIL,不会更快)
start = time.time()
t1 = threading.Thread(target=count, args=(50000000,))
t2 = threading.Thread(target=count, args=(50000000,))
t1.start(); t2.start()
t1.join(); t2.join()
print("多线程耗时:", time.time() - start)  # 可能约 5.5 秒

I/O 密集型任务
在 I/O 操作(如网络请求、文件读写)时,线程会主动释放 GIL,因此多线程仍然可以提升性能:

import threading
import requestsdef fetch_url(url):response = requests.get(url)print(f"{url} 请求完成")urls = ["https://example.com", "https://google.com", "https://github.com"]# 单线程
start = time.time()
for url in urls:fetch_url(url)
print("单线程耗时:", time.time() - start)  # 约 3 秒# 多线程
start = time.time()
threads = []
for url in urls:t = threading.Thread(target=fetch_url, args=(url,))t.start()threads.append(t)
for t in threads:t.join()
print("多线程耗时:", time.time() - start)  # 约 1 秒

解决办法:
1、多进程(multiprocessing):适用于CPU 密集型计算(如机器学习)
每个 Python 进程有独立的 GIL,可以真正并行:

from multiprocessing import Pooldef compute(n):return sum(range(n))if __name__ == "__main__":with Pool(4) as p:results = p.map(compute, [10**7, 10**7, 10**7, 10**7])print(results)

2、 使用 C 扩展:

# Cython 示例
with nogil:# 这里可以执行无 GIL 的 C 代码pass

3、使用异步编程(asyncio):适用于高并发 I/O 操作、Web 服务器、爬虫、高并发网络请求。

import asyncioasync def fetch(url):print(f"正在请求 {url}")await asyncio.sleep(1)  # 模拟 I/O 操作return f"{url} 完成"async def main():tasks = [fetch("https://example.com"), fetch("https://google.com")]results = await asyncio.gather(*tasks)print(results)asyncio.run(main())
http://www.xdnf.cn/news/435781.html

相关文章:

  • Java 反射
  • 久坐办公自动提醒休息的工具
  • QLineEdit增加点击回显功能
  • PH热榜 | 2025-05-13
  • arctanx 导数 泰勒展开式证明
  • 机器学习2
  • 鹅厂面试数学题
  • 典籍指数问答模块回答格式修改
  • java中的Optional
  • 如何优化 Linux 服务器的磁盘 I/O 性能
  • 【Nova UI】十五、打造组件库之滚动条组件(上):滚动条组件的起步与进阶
  • 【学习笔记】Shell编程---流程控制语句
  • PNG图片转icon图标Python脚本(简易版) - 随笔
  • 动态规划问题 -- 多状态模型(打家劫舍)
  • Java的进制转换
  • 大模型驱动的写实数字人实时对话:创新与实践
  • 谈谈各种IO模型
  • 算法·KMP
  • 1688 API 接口使用限制
  • 【C++】多线程和多进程
  • Java Spring 事件驱动机制
  • 中医诊所药房开处方调剂库存管理h5/pc开源版开发
  • 提供全球86国/地区进出口税费,46国/地区监管条件,53国/地区税费计算
  • 第二十三天打卡
  • 项目管理系统流程:高效运作的关键所在
  • 使用ADB命令操作Android的apk/aab包
  • [SAP] 通过程序名获取事务码TCode
  • Python实例题:Pvthon实现简单的Web服务器
  • AI 编程新时代!字节 Seed-Coder 重磅登场
  • 第六章QT基础: Lambda表达式补充