Python多进程执行同一函数的常用方法与实战指南

远山来客
远山来客
发布时间:2026-10-10| 2人浏览过
原创

总结Python中使用multiprocessing模块实现多进程并发执行同一函数的三种核心方案,涵盖手动创建进程、Pool进程池批量调度及异步非阻塞提交。结合任务参数配置、结果获取方式与错误回调机制,提供URL并行下载等实战示例,帮助开发者根据场景快速选择最优并发策略。

多进程并发执行目标与方案对比

在Python中,受GIL限制,多线程无法有效利用多核CPU进行并行计算。使用multiprocessing模块可绕过该限制,通过操作系统级进程实现真正的并行处理。以下为执行同一函数的三种主流路径:

  • Process类手动调度:适合进程数量少、需独立监控生命周期或传递不同参数的场景。
  • Pool进程池批量分配:适合输入数据量大、任务同质化的批处理工作,内置负载均衡与资源回收。
  • apply_async异步提交:适合主流程不能中断、需按需获取各节点结果的复杂流水线。

第1步:使用Process类创建独立进程

目的:精确控制每个子进程的启动时机与参数,适用于需要差异化配置的少量任务。

入口:导入multiprocessing.Process,通过target指定函数,args传递元组参数。

import multiprocessing
import time

def worker(task_name, duration):
    print(f"进程 {task_name} 开始执行,预计耗时 {duration} 秒")
    time.sleep(duration)
    print(f"进程 {task_name} 执行完成")
    return f"{task_name} 处理结果"

if __name__ == "__main__":
    processes = []
    tasks = [("任务A", 2), ("任务B", 3), ("任务C", 1)]
    
    # 创建并启动多个进程
    for name, duration in tasks:
        p = multiprocessing.Process(target=worker, args=(name, duration))
        processes.append(p)
        p.start()
        print(f"已启动进程: {name}")
    
    # 等待所有进程完成,防止主进程提前退出
    for p in processes:
        p.join()
    
    print("所有进程执行完毕")

完成状态:控制台按顺序打印启动信息,随后各进程休眠结束后依次打印完成日志,主进程最后输出汇总提示。

第2步:利用Pool进程池自动调度任务

目的:避免频繁创建销毁系统级进程的开销,由父进程自动将数据分块派发给固定数量的工作进程。

入口:multiprocessing.Pool(processes=cpu_count),配合.map()实现阻塞同步返回,或.map_async()实现异步包装。

import multiprocessing
import os

def worker(x):
    print(f"进程 {os.getpid()} 正在处理数据: {x}")
    result = x * x
    return result

if __name__ == "__main__":
    # 创建进程池,线程数通常设为CPU物理核心数
    with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool:
        data = list(range(1, 9))
        
        # map 阻塞式,按输入顺序严格返回结果
        results_sync = pool.map(worker, data)
        print(f"map 同步结果: {results_sync}")
        
        # map_async 非阻塞包装器,内部仍会阻塞至结果就绪
        async_result = pool.map_async(worker, data)
        results_async = async_result.get(timeout=10)
        print(f"map_async 异步包装结果: {results_async}")

完成状态:进程池自动复用工作进程处理全部数据,主进程在调用.get()或.map()时暂停,直至所有分片计算结束并返回有序列表。

第3步:通过apply_async实现异步非阻塞提交

目的:任务提交与结果收集解耦,主线程可在等待期间执行其他逻辑,适合长耗时或依赖外部API的请求。

入口:pool.apply_async(func, args=(param,), callback=None, error_callback=None)。

import multiprocessing
import time
import random

def worker(task_id):
    sleep_time = random.uniform(0.5, 2.0)
    time.sleep(sleep_time)
    return f"任务{task_id} 完成,耗时{sleep_time:.2f}秒"

if __name__ == "__main__":
    with multiprocessing.Pool(4) as pool:
        async_results = []
        for i in range(6):
            # 提交任务,立即返回AsyncResult对象,不阻塞主循环
            result = pool.apply_async(worker, args=(i,))
            async_results.append(result)
        
        print("所有任务已提交,主进程可继续执行其他工作...")
        
        # 遍历收集结果,第一个调用.get()时阻塞直到对应进程产出
        for i, res in enumerate(async_results):
            print(f"[{i}] {res.get()}")

完成状态:6个任务几乎同时派发,各进程因随机睡眠时长不同而先后完成,主进程依次打印结果,整体耗时低于串行执行的总和。

进阶配置:进程间通信、异常处理与性能调优

安全的数据交换通道

进程内存隔离,推荐使用Queue或Manager传递结构化数据:

from multiprocessing import Queue

def queue_worker(q_input, q_output):
    task = q_input.get()
    processed = f"处理后: {task}"
    q_output.put(processed)

异常捕获与重试机制

异步任务若抛出未处理异常,会导致该槽位死锁。必须传入error_callback明确消费错误:

def on_error(err):
    print(f"子任务崩溃,异常类型: {type(err).__name__}, 详情: {err}")

result = pool.apply_async(worker, args=(data,), error_callback=on_error)
try:
    val = result.get(timeout=30)
except Exception as e:
    print(f"获取结果超时或失败: {e}")

chunksize 参数优化

默认情况下map每次向队列推送单个元素,高频IO场景下IPC开销显著。手动指定chunksize可减少进程间通信次数:

# 经验法则:chunksize 设为数据长度除以进程数的整数倍
avg_chunk = max(1, len(data) // multiprocessing.cpu_count())
results = pool.map(worker, data, chunksize=avg_chunk)

实战演练:并行网络请求下载

目的:验证多进程在处理I/O密集型高延迟任务时的吞吐提升效果。

import multiprocessing
import requests

def download_url(url):
    try:
        resp = requests.get(url, timeout=10)
        return f"{url} | 成功 | {len(resp.content)} bytes"
    except requests.RequestException as e:
        return f"{url} | 失败 | {e}"

if __name__ == "__main__":
    targets = [
        "https://httpbin.org/delay/1",
        "https://httpbin.org/delay/2",
        "https://httpbin.org/delay/1"
    ]
    
    with multiprocessing.Pool(3) as pool:
        reports = pool.map(download_url, targets)
    
    for rpt in reports:
        print(rpt)

注意事项:执行此类脚本前请确保已安装第三方库pip install requests。实际生产环境中建议增加重试装饰器与连接池复用策略。

总结与选型建议

Python多进程并发执行同一函数的核心在于权衡控制粒度与自动化程度。纯手工维护Process适合调试与异构参数分发;Pool.map以牺牲一定灵活性为代价换取最简代码与稳定负载均衡;apply_async则填补了流水线异步编排的空白。合理搭配Queue通信、错误回调与chunksize分块,即可覆盖绝大多数CPU与I/O混合加速需求。以上就是Python多进程并发执行同一函数的详细内容,更多关于Python并发编程的技巧资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。