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

Python Web 开发中的多线程与多进程

Python Web 开发中的多线程与多进程

📚 目录

  1. 🌐 多线程与多进程概述
  2. 🔄 threading库:掌控线程并发的艺术
  3. 🚀 multiprocessing库:多进程并行计算的实战
  4. ⚙️ GIL(全局解释器锁)的影响与线程安全性
  5. 🛠️ 多线程与多进程在FastAPI中的应用场景

1. 🌐 多线程与多进程概述

在 Python Web 开发中,高并发和高效处理请求是提升系统性能的关键。在处理大量请求或数据密集型任务时,多线程与多进程是常见的技术方案。两者虽然都属于并发编程的范畴,但在底层实现和适用场景上存在显著差异。

🔑 核心区别

  • 多线程(Threading):在同一进程内开启多个线程,共享内存空间。适用于 I/O 密集型任务。
  • 多进程(Multiprocessing):开启多个进程,每个进程拥有独立的内存空间。适用于 CPU 密集型任务。

✨ 主要特点

  • 线程更轻量,占用资源少,切换速度快。
  • 进程相对独立,稳定性更强,但创建和切换成本较高。

📊 适用场景

  • 当任务涉及大量 I/O 操作(如网络请求、文件读写)时,多线程通常表现更优。
  • 处理复杂计算或大规模数据运算时,多进程能够有效避免 GIL 限制,提高计算效率。

2. 🔄 threading库:掌控线程并发的艺术

Python 的 threading 模块提供了强大的线程管理能力,使开发者能够轻松实现多线程应用。以下是使用 threading 进行多线程开发的详细解析。

🧩 创建线程的基础方法

import threading
import time

# 线程函数
def task(name):
    print(f"线程 {name} 启动")
    time.sleep(2)
    print(f"线程 {name} 完成")

# 创建线程并启动
thread1 = threading.Thread(target=task, args=("A",))
thread2 = threading.Thread(target=task, args=("B",))

thread1.start()
thread2.start()

thread1.join()
thread2.join()

print("所有线程执行完毕")

🔍 代码解析

  • Thread 负责创建线程实例。
  • start() 方法 启动线程,实际调用 run() 方法执行线程任务。
  • join() 方法 阻塞主线程,等待子线程执行完毕。

🚧 线程同步与锁机制

在多线程共享数据时,可能会产生竞态条件(Race Condition)。为避免数据不一致性问题,可以使用线程锁(Lock)。

lock = threading.Lock()
data = 0

# 线程函数,执行加法
def increment():
    global data
    for _ in range(100000):
        with lock:
            data += 1

threads = []
for i in range(4):
    t = threading.Thread(target=increment)
    threads.append(t)
    t.start()

for t in threads:
    t.join()

print(f"最终数据:{data}")

🎯 代码要点

  • 使用 Lock 确保线程间操作的互斥性,避免数据竞争。
  • with lock 语句自动管理锁的获取与释放,简化代码逻辑。

3. 🚀 multiprocessing库:多进程并行计算的实战

multiprocessing 模块提供了进程管理能力,使 Python 能够更好地利用多核 CPU 进行并行计算。

🚧 多进程的实现示例

from multiprocessing import Process
import os

# 进程函数
def task(name):
    print(f"进程 {name} 启动, 进程 ID: {os.getpid()}")
    time.sleep(2)
    print(f"进程 {name} 完成")

if __name__ == "__main__":
    process1 = Process(target=task, args=("A",))
    process2 = Process(target=task, args=("B",))

    process1.start()
    process2.start()

    process1.join()
    process2.join()

    print("所有进程执行完毕")

📌 代码解析

  • 使用 Process 类创建并启动子进程。
  • 每个进程独立执行,不共享全局变量,避免了 GIL 的影响。

4. ⚙️ GIL(全局解释器锁)的影响与线程安全性

🔧 什么是 GIL?

GIL 是 Python 解释器的全局锁机制,确保同一时间只有一个线程执行 Python 字节码。虽然 GIL 在一定程度上保障了线程安全,但也限制了多线程在 CPU 密集型任务中的效率。

🚀 解决方案

  • 使用多进程 multiprocessing 避开 GIL 限制。
  • 使用 Cython 或 JIT 编译器加速代码执行。

5. 🛠️ 多线程与多进程在FastAPI中的应用场景

在 FastAPI 开发中,通过异步编程可以优化 I/O 密集型任务,但在处理复杂计算或大量请求时,多线程与多进程依然是提升性能的重要工具。

🚀 异步与多线程结合

from fastapi import FastAPI
import threading

app = FastAPI()

@app.get("/compute")
def compute():
    def task():
        print("执行复杂计算任务")
        time.sleep(5)
        print("计算完成")

    thread = threading.Thread(target=task)
    thread.start()
    return {"message": "计算任务已提交"}

🌟 实战要点

  • 通过异步接口调用线程,实现计算任务的异步处理。
  • 避免阻塞主线程,提高 API 响应速度。


http://www.kler.cn/a/451422.html

相关文章:

  • Django 模型中使用选择(choices):全面指南
  • stm32基础(keil创建、Proteus仿真、点亮LED灯,7段数码管)
  • 【赵渝强老师】MongoDB逻辑存储结构
  • MySQL for update skip locked 与 for update nowait
  • SDMTSP:粒子群优化算法PSO求解单仓库多旅行商问题,可以更改数据集和起点(MATLAB代码)
  • log4j2漏洞复现(CVE-2021-44228)
  • 2024冬季FORCE大会,火山引擎边缘云全面展示边缘云 + AI 产品技术方案
  • 高德地图自定义折线矢量图形
  • 鸿蒙Next ArkTS语法适配背景概述
  • Java操作Redis
  • [工具]GitHub Copilot 直接提供免费额度了
  • 【IoTDB 线上小课 10】为什么选择 IoTDB 管理时序数据?
  • 2.利用docker进行gitlab服务器迁移
  • rust学习: 有用的命令
  • Datawhale-AI活动2024.12.24
  • 【docker】docker desktop 在windows上支持 host模式
  • SQL语法基础知识总结
  • 抢票神器:大麦网抢票实战教程
  • Qt笔记:文件I/O操作
  • Android studio开启虚拟机闪退、闪屏、死机、电脑重启
  • Web Server for Chrome 使用教程
  • 虚幻引擎结构之AActor
  • 电子应用设计方案70:智能挂钟系统设计
  • C语言——数据在内存中的存储
  • Django REST framework (DRF)中的api_view和APIView权限控制
  • 如何设置爬虫的访问频率?