python进程池的简单使用

本文介绍Python中multiprocessing模块的使用,包括进程池的创建与管理,异步执行任务的方法,以及如何处理任务执行后的回调和错误信息。通过具体示例展示了apply_async函数的应用,以及自定义进程类实现异步任务。
  1. 进程池存在,multiprocessing模块中.
  2. multiprocessing.Pool(processes=4)指定创建进程的个数。
  3. pool.apply_async 异步执行任务.
  4. callback的参数是,任务执行的返回值。
  5. error_callback,的参数是执行的错误信息。
import multiprocessing
import time


def task_1(name, age):
    time.sleep(3)
    # print(1 / 0)
    print('name:', name, 'age:', age, '\n')
    print('执行task1', '\n')
    return '返回值'


def task_1_call_back(args):
    print('task_1_call_back:', args, '\n')


def task1_error_callback(args):
    print('test_error_callback:', args, '\n')


if __name__ == '__main__':
    """pool不能再外面,否则会报错"""
    """task_1_call_back 的参数就是 task 执行的返回值"""
    """task1_error_callback 的参数就是 task 执行错误的信息"""
    pool = multiprocessing.Pool(4)
    t = pool.apply_async(func=task_1,
                         args=('name', 'age'),
                         callback=task_1_call_back,
                         error_callback=task1_error_callback)
    pool.close()
    pool.join()

方法二:

import multiprocessing
import time


def test_run():
    print('test_run....')
    time.sleep(3)
    return 'success'


def test_run_cal_back(args):
    print('test_run_cal_back....', args)


class ProcessAsnyc(multiprocessing.Process):
    def __init__(self, *args, action=None):
        super(ProcessAsnyc, self).__init__()
        self.args = args
        self.action = action

    def run(self):
        """
        开始执行导出动作
        :return:
        """
        if len(self.args) > 0:
            self.action(self.args)
        else:
            self.action()


if __name__ == '__main__':
    process = ProcessAsnyc(action=test_run)
    process.start()
    process.close()
<think>我们被要求回答关于Python进程池使用方法及示例。根据引用内容,我们可以从多个角度来讲解。 引用[1]提到进程池multiprocessing模块提供的用于管理进程的方式。 引用[2]和[3]提供了进程池的示例代码。 引用[4]指出进程池适用于CPU密集型任务,而线程池适用于I/O密集型任务。 引用[5]展示了使用进程池时如何传递参数和收集结果。 我们将从以下几个方面进行说明: 1. 创建进程池 2. 提交任务的方法:apply_async(异步提交)、apply(同步提交)、map、imap等 3. 获取任务结果 4. 关闭进程池并等待任务完成 5. 使用上下文管理器(with语句)管理进程池 6. 异常处理 注意:由于用户之前询问的是线程池,现在转向进程池,我们可以对比一下两者的适用场景(根据引用[4])。 示例代码将参考引用[2]、[3]、[5]进行整合,并添加详细注释。 另外,我们还需要注意,在Windows系统上使用多进程时,必须将代码放在`if __name__ == '__main__':`中,以避免子进程递归执行。 下面开始组织回答。</think>### Python进程池使用方法详解 进程池适用于**CPU密集型任务**(如数学计算、图像处理),可绕过GIL限制充分利用多核CPU。以下是核心用法及示例(基于`multiprocessing.Pool`): --- #### 1. 基础使用流程 ```python from multiprocessing import Pool import os def task(x): print(f"进程 {os.getpid()} 处理任务 {x}") return x * x # 模拟CPU计算 if __name__ == '__main__': with Pool(processes=4) as pool: # 创建4个进程的池 results = pool.map(task, range(10)) # 批量提交任务 print("计算结果:", results) ``` **输出示例**: ``` 进程 1234 处理任务 0 进程 1235 处理任务 1 进程 1236 处理任务 2 进程 1237 处理任务 3 ... 计算结果: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] ``` --- #### 2. 异步任务处理 使用`apply_async`实现非阻塞提交: ```python def task(x): return x ** 2 if __name__ == '__main__': with Pool(4) as pool: futures = [pool.apply_async(task, (i,)) for i in range(5)] results = [f.get(timeout=10) for f in futures] # 超时获取结果 print(results) # [0, 1, 4, 9, 16] ``` --- #### 3. 进程间共享数据 通过`Manager`实现跨进程数据共享: ```python from multiprocessing import Pool, Manager def worker(x, shared_list): shared_list.append(x * x) return x if __name__ == '__main__': with Manager() as manager: shared_list = manager.list() # 共享列表 with Pool(2) as pool: # 传递共享对象到子进程 pool.starmap(worker, [(i, shared_list) for i in range(5)]) print("共享结果:", list(shared_list)) # [0, 1, 4, 9, 16] ``` --- #### 4. 高级功能示例 **动态控制任务流**: ```python def task(x): if x % 2 == 0: return x * 2 else: raise ValueError(f"奇数错误: {x}") if __name__ == '__main__': with Pool(2) as pool: try: # 使用imap_unordered获取结果(按完成顺序) for res in pool.imap_unordered(task, range(5)): print("收到结果:", res) except Exception as e: print("捕获异常:", e) ``` --- ### 关键参数说明 | **方法** | **作用** | **适用场景** | |------------------|----------------------------------------|--------------------------| | `pool.map()` | 批量提交任务,按顺序返回结果 | 简单并行任务 | | `pool.apply_async()` | 异步提交单个任务,返回AsyncResult对象 | 需控制任务提交时机 | | `pool.starmap()` | 支持多参数的任务批量提交 | 参数为元组的任务 | | `pool.close()` | 禁止新任务加入 | 准备结束进程池 | | `pool.join()` | 阻塞等待所有任务完成 | 清理阶段使用 | --- ### 注意事项 1. **必须使用`if __name__ == '__main__'`** 避免Windows系统下的递归创建进程问题[^1] 2. **进程间通信成本高** 共享数据需通过`Manager`或`Queue`,避免直接传递大对象 3. **进程池初始化开销大** 适合长时间运行的任务,短任务可能适得其反 4. **异常处理** 子进程异常需在主进程捕获(如示例4) > 对比线程池:进程池适用于CPU密集型任务,线程池适用于I/O密集型任务(如网络请求)[^4]。 --- ### 完整示例(带异常处理) ```python from multiprocessing import Pool import time def task(x): try: time.sleep(0.5) if x == 3: raise ValueError("特殊错误") return x * 2 except Exception as e: return f"任务失败: {str(e)}" if __name__ == '__main__': with Pool(3) as pool: results = [] # 提交10个任务 for i in range(10): future = pool.apply_async(task, (i,)) results.append(future) # 获取结果 for idx, f in enumerate(results): try: print(f"任务{idx}结果: {f.get(timeout=2)}") except Exception as e: print(f"任务{idx}超时或异常: {str(e)}") ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

永不止步——

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值