资讯详情

资讯详情

Python并发04:多进程加多协程混合模式的分层并发设计

多进程 多协程混合模式的分层并发设计很多真实任务既有 I/O 等待又有 CPU 计算。只用多进程时进程会在等待 I/O 时闲置只用多协程时计算部分仍受 GIL 限制。混合模式把两者组合起来外层用进程池获得多核并行能力内层用协程池重叠 I/O 等待。异步 I/OCPU 计算异步 I/O复合任务读取、计算、写入按数据分片进程 1进程 2协程 1协程 2协程 1协程 2读数据平方和写结果一、为什么需要混合模式数据管道类任务通常由三步组成从数据库或网络异步读取数据I/O 密集。对读取到的数据做复杂统计计算CPU 密集。把结果异步写回数据库I/O 密集。如果只用多进程每个进程都必须等待 I/OCPU 会空闲。如果只用协程计算阶段仍然无法利用多核。因此可以用“外层多进程、内层多协程”的方式各取所长。只用多进程I/O 等待时 CPU 闲置只用多协程CPU 计算受 GIL 限制混合模式进程负责并行计算协程负责重叠 I/O二、双层架构与职责划分可以把混合模式想象成一家现代化工厂外层进程池相当于多个车间每个车间独立运行数量通常接近 CPU 核心数。内层协程池相当于车间里的流水线工人负责处理 I/O 等待和轻量计算。例如处理 1 亿条用户行为日志将数据分成 4 份每份交给一个进程。每个进程启动 3 个协程分别负责读取、清洗和写入。某个协程等待数据时其他协程继续计算。这样既能绕开 GIL又不会让 I/O 等待浪费 CPU。三、数据如何流转进程之间的数据传递要尽量轻量策略说明数据分片按行、ID 范围或时间切分例如data_01.csv、data_02.csvIPC 少传大数据传递文件路径或查询条件让子进程自己读取数据进程内协程协作同一进程内的协程共享内存可以直接高效调度原始大数据分片 1 / 分片 2 / 分片 3 / 分片 4只传递路径或查询条件进程 1 自行读取进程 2 自行读取进程内协程并发四、优势互补单一模式的问题混合模式如何解决多进程处理 I/O 时容易干等每个进程内部用协程并发处理 I/O多协程无法发挥多核性能外层用多进程并行执行计算任务复杂任务流程卡在某一步分阶段设计I/O 用协程计算用进程适合混合模式的典型任务包括数据管道读、算、存。批量报表拉取数据、聚合计算、写入结果。高并发后台服务接请求、查库、计算、返回。五、混合模式示例下面的示例把 1 到 4000 分成 4 个数据分片外层进程池并行处理内层每个进程用 3 个协程处理异步 I/O 和计算。importmultiprocessingimportasyncioimporttimeasyncdefasync_worker(task_id,data_chunk,process_name): 进程内的协程处理异步 I/O 与轻量计算 print(f[{time.strftime(%X)}]{process_name}- 协程{task_id}开始处理数据分片长度{len(data_chunk)})awaitasyncio.sleep(1)resultsum(x*xforxindata_chunk)print(f[{time.strftime(%X)}]{process_name}- 协程{task_id}处理完成结果{result})returnresultasyncdefprocess_inner_logic(data_chunk,process_name): 单个进程的内部逻辑创建协程池处理当前进程的数据分片 coroutines[async_worker(i,data_chunk,process_name)foriinrange(3)]coro_resultsawaitasyncio.gather(*coroutines)returnsum(coro_results)defprocess_worker(data_chunk): 进程工作函数初始化事件循环执行进程内协程逻辑 process_namemultiprocessing.current_process().namereturnasyncio.run(process_inner_logic(data_chunk,process_name))defmain():print( Python 混合模式多进程 多协程)start_timetime.time()data_chunks[list(range(1,1001)),list(range(1001,2001)),list(range(2001,3001)),list(range(3001,4001)),]withmultiprocessing.Pool(processes2)aspool:process_resultspool.map(process_worker,data_chunks)final_resultsum(process_results)end_timetime.time()total_durationend_time-start_timeprint(\n 混合模式任务执行完成 )print(f各进程计算结果{process_results})print(f最终总结果所有分片平方和之和{final_result})print(f总耗时{total_duration:.2f}秒)pure_process_duration4*10.5print(f若用纯多进程无协程理论耗时≈{pure_process_duration:.2f}秒混合模式效率提升≈{pure_process_duration/total_duration:.1f}倍)if__name____main__:main()在 2 核 CPU 环境中示例输出可能如下 Python 混合模式多进程 多协程 [17:00:00] SpawnPoolWorker-1 - 协程 0开始处理数据分片长度1000 [17:00:00] SpawnPoolWorker-1 - 协程 1开始处理数据分片长度1000 [17:00:00] SpawnPoolWorker-1 - 协程 2开始处理数据分片长度1000 [17:00:00] SpawnPoolWorker-2 - 协程 0开始处理数据分片长度1000 [17:00:00] SpawnPoolWorker-2 - 协程 1开始处理数据分片长度1000 [17:00:00] SpawnPoolWorker-2 - 协程 2开始处理数据分片长度1000 [17:00:01] SpawnPoolWorker-1 - 协程 0处理完成结果333833500 [17:00:01] SpawnPoolWorker-1 - 协程 1处理完成结果333833500 [17:00:01] SpawnPoolWorker-1 - 协程 2处理完成结果333833500 [17:00:01] SpawnPoolWorker-2 - 协程 0处理完成结果1667167500 [17:00:01] SpawnPoolWorker-2 - 协程 1处理完成结果1667167500 [17:00:01] SpawnPoolWorker-2 - 协程 2处理完成结果1667167500 [17:00:01] SpawnPoolWorker-1 - 协程 0开始处理数据分片长度1000 [17:00:01] SpawnPoolWorker-1 - 协程 1开始处理数据分片长度1000 [17:00:01] SpawnPoolWorker-1 - 协程 2开始处理数据分片长度1000 [17:00:01] SpawnPoolWorker-2 - 协程 0开始处理数据分片长度1000 [17:00:01] SpawnPoolWorker-2 - 协程 1开始处理数据分片长度1000 [17:00:01] SpawnPoolWorker-2 - 协程 2开始处理数据分片长度1000 [17:00:02] SpawnPoolWorker-1 - 协程 0处理完成结果4501500500 [17:00:02] SpawnPoolWorker-1 - 协程 1处理完成结果4501500500 [17:00:02] SpawnPoolWorker-1 - 协程 2处理完成结果4501500500 [17:00:02] SpawnPoolWorker-2 - 协程 0处理完成结果9335834500 [17:00:02] SpawnPoolWorker-2 - 协程 1处理完成结果9335834500 [17:00:02] SpawnPoolWorker-2 - 协程 2处理完成结果9335834500 混合模式任务执行完成 各进程计算结果[1001500500, 5001502500, 13504501500, 28007503500] 最终总结果所有分片平方和之和47515008000 总耗时2.15 秒 若用纯多进程无协程理论耗时≈4.50 秒混合模式效率提升≈2.1 倍从结果可以看出两层并发同时生效外层进程并行处理分片内层协程在 1 秒 I/O 等待期间继续调度其他任务。六、混合模式适用场景具体场景适配逻辑大数据分析异步读取分片数据多进程并行计算异步存储结果分布式爬虫多进程按域名拆分任务进程内协程并发发起请求高并发 API 服务多进程处理请求进程内协程异步查询数据库并计算视频处理多进程按视频分片转码进程内协程异步读写元数据小结混合模式不是简单叠加两种技术而是分层解决不同瓶颈进程层突破 GIL协程层重叠 I/O。实现时需要控制进程数量、分片均衡和进程间数据传递的体积。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →