python主进程 子进程_pool主进程捕获子进程异常

本文介绍了在Python中,主进程如何捕获并处理子进程的异常情况。通过示例代码展示了使用multiprocessing模块创建子进程,主进程通过`apply_async`和`result.get()`结合try-except结构来捕获子进程的异常信息。文章还分析了在子进程和主进程中直接捕获异常的不足,并提供了正确的实现方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题背景:

主进程做任务调度,子进程做任务执行,子进程定时返回进度信息,主进程获取进度,进度为100时,子进程任务结束。子进程执行过程中如果有异常,主进程需要捕获

python多进程调度, 主进程如何捕获子进程的异常,这个问题困扰了好久,网上看了好多方法都不是我想要的,整理了一下遇到的一些坑

为了简化子进程任务实现,和主进程的任务等待的过程,直接用time.sleep(),先看下最终实现方案:

from multiprocessing import Pool

import time

def sub_task():

print "sub_task():enter sub_task"

loop_num = 0

while True:

print "sub_task:enter sub process loop"

if loop_num > 1:

print 'sub_task():sub_task finish'

raise Exception("sub_task has error")

loop_num += 1

time.sleep(1)

if __name__ == "__main__":

try:

proc_pool = Pool(processes=6)

result = proc_pool.apply_async(sub_task, args=())

proc_pool.close()

count = 0

while True:

print "main():enter main process loop"

time.sleep(2)

if result.ready():

print 'main():sub process is finish'

result.ge

Python 中的 `multiprocessing` 模块用于创建和管理多个进程,以充分利用多核处理器的能力。它支持跨平台使用,并通过 `Process` 类、`Pool` 类以及共享内存机制来实现并行任务处理。 ### 基本用法 #### 创建进程 可以使用 `multiprocessing.Process` 类来定义一个独立运行的任务: ```python import multiprocessing def worker(): print('Worker process') if __name__ == '__main__': p = multiprocessing.Process(target=worker) p.start() p.join() ``` #### 使用进程池 如果需要执行大量任务,推荐使用 `multiprocessing.Pool` 来复用进程资源: ```python from multiprocessing import Pool def square(x): return x * x if __name__ == '__main__': with Pool(4) as pool: # 创建包含4个进程的池 results = pool.map(square, [1, 2, 3, 4, 5]) print(results) ``` #### 共享内存与通信 进程间可以通过 `Value` 和 `Array` 实现共享内存,或者使用 `Queue` 或 `Pipe` 进行通信: ```python from multiprocessing import Process, Value, Array def modify(n, a): n.value = 3.1415927 for i in range(len(a)): a[i] = -a[i] if __name__ == '__main__': num = Value('d', 0.0) arr = Array('i', range(10)) p = Process(target=modify, args=(num, arr)) p.start() p.join() print(num.value) print(arr[:]) ``` ### 常见问题及解决方法 #### 子进程无法启动或卡住 在某些平台上(尤其是 Windows),子进程可能因主程序没有正确保护入口点而失败。确保使用了 `if __name__ == '__main__':` 来防止递归启动。 #### 资源泄漏或死锁 当多个进程等待彼此释放资源时可能会发生死锁。建议避免复杂的同步逻辑,尽量使用高阶 API 如 `Pool.map()` 等简化并发控制。 #### 数据竞争与同步 不同进程访问共享数据时可能发生冲突。可以借助 `multiprocessing.Lock` 来确保线程安全操作: ```python from multiprocessing import Process, Lock def synchronized_print(l, text): l.acquire() print(text) l.release() if __name__ == '__main__': lock = Lock() processes = [] for i in range(5): p = Process(target=synchronized_print, args=(lock, f'Process {i}')) processes.append(p) p.start() for p in processes: p.join() ``` #### 多进程与全局解释器锁 (GIL) 尽管 `multiprocessing` 绕过了 GIL 的限制[^1],但需要注意每个进程都有自己独立的 GIL,因此适用于 CPU 密集型任务。对于 I/O 密集型任务,通常更适合使用 `threading` 或异步库如 `asyncio`。 #### 异常处理 在子进程中抛出的异常不会自动传播到父进程。可以通过捕获异常并将信息传递回主进程进行处理: ```python from multiprocessing import Process import sys def faulty(): try: raise RuntimeError("Something went wrong") except Exception as e: print(f"Caught error: {e}") sys.exit(1) if __name__ == '__main__': p = Process(target=faulty) p.start() p.join() print(f"Exit code: {p.exitcode}") ``` #### 性能优化 - **选择合适的进程数量**:通常设置为 CPU 核心数。 - **减少进程间通信开销**:尽量减少 `Queue` 或 `Pipe` 的频繁读写。 - **使用 `daemon` 属性**:将不需要长时间运行的进程设为守护进程,随主进程退出而终止。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值