Python使用多进程执行同一个函数的多种方法
作者:独隅
本文介绍了在Python中使用多进程执行相同函数的三种方法:Process类、Pool进程池和apply_async异步执行,比较了各种方法的适用场景、优缺点,并提供了实用技巧和注意事项,推荐使用Pool进程池处理大量任务,它简单易用且自动负载均衡,需要的朋友可以参考下
在 Python 中,使用多进程执行同一个函数有多种方法,主要可以通过 multiprocessing 模块实现。以下是几种常用的方式:
方法一:使用 Process 类创建独立进程
这种方法适合需要精确控制每个进程的场景。
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("所有进程执行完毕")
方法二:使用 Pool 进程池(推荐)
进程池更适合处理大量任务,可以自动管理进程的创建和回收。
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 = [1, 2, 3, 4, 5, 6, 7, 8]
# 方法1: map - 阻塞式,按顺序返回结果
results = pool.map(worker, data)
print(f"map 结果: {results}")
# 方法2: map_async - 非阻塞式
async_result = pool.map_async(worker, data)
results_async = async_result.get() # 获取结果时会阻塞
print(f"map_async 结果: {results_async}")
方法三:使用 apply_async 实现异步执行
适合需要更灵活控制任务提交和结果获取的场景。
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):
result = pool.apply_async(worker, args=(i,))
async_results.append(result)
print("所有任务已提交,主进程可继续执行其他工作...")
# 按完成顺序获取结果(无序)
for result in async_results:
print(result.get()) # 阻塞直到有结果可用
方法对比与选择指南
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| Process | 进程数少,需要精细控制 | 控制灵活,可设置不同参数 | 需要手动管理进程生命周期 |
| Pool.map | 批量处理相同任务 | 简单易用,自动负载均衡 | 必须等待所有任务完成 |
| Pool.apply_async | 异步任务处理 | 非阻塞,效率高 | 结果获取稍复杂 |
实用技巧与注意事项
- 进程间通信:使用
Queue进行数据传递
def worker(queue):
data = queue.get()
processed = f"处理后的: {data}"
queue.put(processed)
- 错误处理:使用回调函数处理异常
def error_callback(error):
print(f"任务执行出错: {error}")
pool.apply_async(worker, args=(data,), error_callback=error_callback)
- 性能优化:合理设置进程数和 chunksize
# 根据任务类型调整参数 results = pool.map(worker, data, chunksize=len(data)//multiprocessing.cpu_count())
实际应用示例:并行下载任务
import multiprocessing
import requests
def download_url(url):
try:
response = requests.get(url, timeout=10)
return f"{url}: 成功, 大小 {len(response.content)} bytes"
except Exception as e:
return f"{url}: 失败, 错误 {str(e)}"
if __name__ == "__main__":
urls = [
"https://httpbin.org/delay/1",
"https://httpbin.org/delay/2",
"https://httpbin.org/delay/1"
]
with multiprocessing.Pool(3) as pool:
results = pool.map(download_url, urls)
for result in results:
print(result)
根据你的具体需求选择合适的方案,Pool 进程池 在大多数情况下都是最实用和高效的选择。
以上就是Python使用多进程执行同一个函数的多种方法的详细内容,更多关于Python多进程执行同一个函数的资料请关注脚本之家其它相关文章!
