跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Python算法

Python 并发编程实战:多线程与多进程详解

Python 并发编程实战涉及多线程、多进程及线程池的应用。文章解析 threading 与 multiprocessing 库的核心用法,对比 GIL 对性能的影响。通过文件下载与数据处理案例,展示 concurrent.futures 如何简化异步任务管理。重点讲解锁机制与条件变量在共享资源保护中的作用,提供可落地的工程化代码示例,助力开发者提升程序执行效率。

w795471发布于 2026/3/29更新于 2026/7/1828 浏览
Python 并发编程实战:多线程与多进程详解

Python 并发编程实战:多线程与多进程详解

一、并发编程基础

在开发高响应度的应用时,并发编程是绕不开的话题。简单来说,它允许程序同时执行多个任务,无论是线程还是进程,都能显著提升执行效率并充分利用系统资源。

1.1 核心优势与应用场景

并发编程的价值主要体现在三个方面:

  • 提升效率:并行处理减少总运行时间。
  • 资源利用:避免 CPU 或内存闲置。
  • 结构优化:通过模块化设计简化复杂逻辑。

根据任务类型选择方案至关重要:CPU 密集型(如数学计算)适合多进程,而 I/O 密集型(如文件读写、网络请求)则更适合多线程。

二、多线程编程实践

2.1 线程的创建与管理

使用 threading 模块可以方便地管理线程。下面是一个简单的示例,展示如何启动并等待线程结束。

import threading
import time

def thread_function(name):
    print(f'线程 {name} 开始')
    time.sleep(2)
    print(f'线程 {name} 结束')

# 创建线程
thread1 = threading.Thread(target=thread_function, args=('Thread 1',))
thread2 = threading.Thread(target=thread_function, args=('Thread 2',))

# 启动线程
thread1.start()
thread2.start()

# 等待线程结束
thread1.join()
thread2.join()
print('所有线程结束')

2.2 同步与互斥机制

当多个线程访问共享资源时,必须防止数据竞争。这里使用互斥锁(Lock)来保护计数器。

import threading
import time

counter = 0
lock = threading.Lock()

def thread_function(name):
    global counter
    print(f'线程 {name} 开始')
    
    lock.acquire()
    try:
        counter += 1
        print(f'线程 {name} 已修改共享资源,值为 {counter}')
    finally:
        lock.release()
    
    time.sleep(2)
    print(f'线程 {name} 结束')

threads = []
for i in range(5):
    thread = threading.Thread(target=thread_function, args=(f'Thread {i}',))
    threads.append(thread)
    thread.start()

for thread in threads:
    thread.join()

print(f'所有线程结束,共享资源的值为 {counter}')

2.3 线程池的使用

手动管理线程比较繁琐,concurrent.futures 提供的线程池能自动调度工作线程。

import concurrent.futures
import time

def thread_function(name):
    print(f'线程 {name} 开始')
    time.sleep(2)
    print(f'线程 {name} 结束')
    return name

with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
    future1 = executor.submit(thread_function, 'Thread 1')
    future2 = executor.submit(thread_function, 'Thread 2')
    future3 = executor.submit(thread_function, 'Thread 3')

    print(f'线程 {future1.result()} 完成')
    print(f'线程 {future2.result()} 完成')
    print(f'线程 {future3.result()} 完成')
    print('所有线程结束')

三、多进程编程实践

3.1 进程的创建与管理

对于 CPU 密集型任务,多进程能绕过 GIL 限制,真正利用多核 CPU。

import multiprocessing
import time

def process_function(name):
    print(f'进程 {name} 开始')
    time.sleep(2)
    print(f'进程 {name} 结束')

process1 = multiprocessing.Process(target=process_function, args=('Process 1',))
process2 = multiprocessing.Process(target=process_function, args=('Process 2',))

process1.start()
process2.start()

process1.join()
process2.join()
print('所有进程结束')

3.2 进程间通信

进程之间默认隔离,需要通过管道(Pipe)或队列进行通信。

import multiprocessing
import time

def process_function(conn):
    print(f'子进程发送数据')
    conn.send('Hello from child process')
    time.sleep(2)
    print(f'子进程结束')
    conn.close()

parent_conn, child_conn = multiprocessing.Pipe()
process = multiprocessing.Process(target=process_function, args=(child_conn,))
process.start()

print(f'父进程接收数据:{parent_conn.recv()}')
process.join()
print('所有进程结束')

3.3 进程池的使用

类似线程池,进程池也支持批量提交任务。

import concurrent.futures
import time

def process_function(name):
    print(f'进程 {name} 开始')
    time.sleep(2)
    print(f'进程 {name} 结束')
    return name

with concurrent.futures.ProcessPoolExecutor(max_workers=3) as executor:
    future1 = executor.submit(process_function, 'Process 1')
    future2 = executor.submit(process_function, 'Process 2')
    future3 = executor.submit(process_function, 'Process 3')

    print(f'进程 {future1.result()} 完成')
    print(f'进程 {future2.result()} 完成')
    print(f'进程 {future3.result()} 完成')
    print('所有进程结束')

四、高级同步控制

除了基本的锁,条件变量(Condition)能实现更复杂的生产者 - 消费者模型。

import threading
import time

items = []
condition = threading.Condition()

def producer():
    for i in range(5):
        with condition:
            items.append(i)
            print(f'生产者生产了 {i}')
            condition.notify()
        time.sleep(1)

def consumer():
    for i in range(5):
        with condition:
            while not items:
                condition.wait()
            item = items.pop(0)
            print(f'消费者消费了 {item}')
        time.sleep(1)

producer_thread = threading.Thread(target=producer)
consumer_thread = threading.Thread(target=consumer)

producer_thread.start()
consumer_thread.start()

producer_thread.join()
consumer_thread.join()
print('所有线程结束')

五、实战案例:并发下载文件

在实际业务中,我们常需要批量下载资源。下面演示如何使用线程池加速这一过程。

5.1 需求分析

  • 支持并发下载多个文件。
  • 显示下载进度。
  • 处理下载失败的情况。

5.2 代码实现

import requests
import concurrent.futures
import os

def download_file(url, save_path):
    try:
        response = requests.get(url, stream=True)
        response.raise_for_status()
        with open(save_path, 'wb') as file:
            for chunk in response.iter_content(chunk_size=8192):
                if chunk:
                    file.write(chunk)
        print(f'文件 {save_path} 下载成功')
        return save_path
    except Exception as e:
        print(f'文件 {save_path} 下载失败:{e}')
        return None

def download_files(urls, save_dir, max_workers=5):
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)
    
    save_paths = [os.path.join(save_dir, os.path.basename(url)) for url in urls]
    
    with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = [executor.submit(download_file, url, save_path) for url, save_path in zip(urls, save_paths)]
        
        for future in concurrent.futures.as_completed(futures):
            future.result()

if __name__ == '__main__':
    urls = [
        'https://www.example.com/page1.html',
        'https://www.example.com/page2.html',
        'https://www.example.com/page3.html',
        'https://www.example.com/page4.html',
        'https://www.example.com/page5.html'
    ]
    save_dir = 'downloads'
    download_files(urls, save_dir)

六、实战案例:并发数据处理

面对大量 CSV 文件,单线程处理往往太慢。利用多进程可以显著缩短统计耗时。

6.1 需求分析

  • 并发处理多个数据文件。
  • 计算数据的统计信息。
  • 保存处理结果。

6.2 代码实现

import pandas as pd
import concurrent.futures
import os

def process_file(file_path):
    try:
        df = pd.read_csv(file_path)
        stats = {
            '文件名': os.path.basename(file_path),
            '行数': df.shape[0],
            '列数': df.shape[1],
            '平均值': df.mean().to_dict(),
            '最大值': df.max().to_dict(),
            '最小值': df.min().to_dict()
        }
        print(f'文件 {os.path.basename(file_path)} 处理成功')
        return stats
    except Exception as e:
        print(f'文件 {os.path.basename(file_path)} 处理失败:{e}')
        return None

def process_files(file_paths, max_workers=5):
    with concurrent.futures.ProcessPoolExecutor(max_workers=max_workers) as executor:
        futures = [executor.submit(process_file, file_path) for file_path in file_paths]
        results = []
        for future in concurrent.futures.as_completed(futures):
            result = future.result()
            if result:
                results.append(result)
    return results

def save_results(results, save_path):
    df = pd.DataFrame(results)
    df.to_csv(save_path, index=False)
    print(f'处理结果已保存到 {save_path}')

if __name__ == '__main__':
    file_paths = ['data1.csv', 'data2.csv', 'data3.csv', 'data4.csv', 'data5.csv']
    save_path = 'results.csv'
    results = process_files(file_paths)
    save_results(results, save_path)

七、结语

掌握并发编程的关键在于理解不同场景下的资源调度策略。I/O 操作优先选线程,计算密集优先选进程。配合 concurrent.futures 库,可以大幅降低异步开发的复杂度。建议在实际项目中多尝试这两种模式,根据性能瓶颈灵活调整。

目录

  1. Python 并发编程实战:多线程与多进程详解
  2. 一、并发编程基础
  3. 1.1 核心优势与应用场景
  4. 二、多线程编程实践
  5. 2.1 线程的创建与管理
  6. 创建线程
  7. 启动线程
  8. 等待线程结束
  9. 2.2 同步与互斥机制
  10. 2.3 线程池的使用
  11. 三、多进程编程实践
  12. 3.1 进程的创建与管理
  13. 3.2 进程间通信
  14. 3.3 进程池的使用
  15. 四、高级同步控制
  16. 五、实战案例:并发下载文件
  17. 5.1 需求分析
  18. 5.2 代码实现
  19. 六、实战案例:并发数据处理
  20. 6.1 需求分析
  21. 6.2 代码实现
  22. 七、结语
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 前端国际化实战指南:构建全球化应用
  • DeepSeek-OCR-WebUI 部署指南:支持 7 种识别模式与 GPU 加速
  • GLM-4.7 与 MiniMax M2.1 工程级 Agent 模型接入实战
  • 多模态赋能情绪理解:Qwen3-VL+LLaMA-Factory 的人脸情绪识别实战
  • GLM-4.6V-Flash-WEB 食物识别与热量估算实战
  • Python 临床知识问答与检索项目架构设计与实现
  • Python 爬取小红书笔记数据及词云可视化分析
  • 2024 年转行 AI 产品经理的时机分析与准备指南
  • Flutter llm_json_stream 鸿蒙化适配与流式 JSON 解析指南
  • AI 驱动的虚拟现实与增强现实开发
  • 动态规划路径类 DP 入门:3 道经典例题解析
  • 本科生如何系统自学机器学习
  • Vue3 方法调用报错“不存在”?通常是 setup 作用域问题
  • AI 智能体 (Agent) 的 5 个能力级别详解
  • 网络安全就业前景与核心岗位详解
  • 通义万相 2.1 文生视频技术解析与部署实践
  • Spring Web 模块核心解析与 RESTful API 实战
  • VMware 安装 CentOS 7 图文教程
  • Star-Office-UI:像素风格 AI 办公室看板,可视化 AI 助手工作状态
  • AI 编程:自动化代码生成、低代码开发与算法优化实践

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online