聊聊Python多进程

写在前面

之前一直没关注过多进程这方面,朋友问起时感觉很奇怪,因为进程是资源分配的最小单元,线程是运算调度的最小单元,代码程序本质上只是一些文本文件,给他分配对应的资源运行起来才是进程,那为什么会有多进程呢?看了看文档发现原来是通过创建子进程并管理来实现多进程。

多进程和多线程有什么区别?

虽然同样是并发,同样是均衡CPU与IO之间差距过大的运行速率,多线程是多个线程共享一个CPU,好处是线程间通信或切换很容易,坏处是目前CPU都是多核的,很容易出现一核有难八核围观的问题,同时python具有GIL(全局锁),让每个CPU在同一时间只能执行一个线程,这让我们很难实现并行计算。而多进程避免了这个问题,同时也要注意,多个进程之间的通信与切换成本更大。

因此python的多线程并不适合CPU密集型的任务,更适合IO密集型的任务

fork vs spawn

fork速度会更快,因为他是对父进程的整个虚拟内存进行写时复制,包括已经初始化过的python解释器,内存中构造的对象,而不需要识别哪些资源是必要的,仅将内存页作为一个整体复制。但这也会带来问题,比如由于fork不会复制父进程的线程,如果其他线程持有的存储在内存中的锁也被复制的话,但是因为没有对应的线程进行解锁,就会导致死锁。

spawn从头开始启动一个python子进程,所以安全,不继承父进程的资源,所以也不臃肿,但是启动会较慢。

进程池

进程池Pool 会帮我们实现简单的多进程任务,我们可以通过apply() 和map() 来执行任务并阻塞直到子进程计算完成任务。看下官网代码:

Python 复制代码
import multiprocessing

def function_square(data):
    result = data*data
    return result

if __name__ == '__main__':
    inputs = list(range(100))
    pool = multiprocessing.Pool(processes=4)
    pool_outputs = pool.map(function_square, inputs)
    pool.close()
    pool.join()
    print ('Pool    :', pool_outputs)

map可以将可迭代的数据的每一个元素作为一个任务来执行。任务执行结束后可以通过 pool.close() 告诉进程池不再接受新的任务,而pool.join()会一直阻塞,知道进程池中的所有工作进程都结束。

有点反常,在使用map的情况下是否不再需要join?

笔者自己试了下,确实不需要在pool.map后添加join。

相关推荐
红尘散仙2 小时前
我把终端小说阅读器接上了 AI Agent:TRNovel 现在能用 skill 生成书源了
人工智能·后端·rust
心中有国也有家2 小时前
GE图引擎深度解析——CANN的计算图优化与执行引擎
人工智能·pytorch·python·学习·numpy
卷毛的技术笔记3 小时前
告别硬编码!Spring AI Alibaba 实现 AI Agent 智能工具调用(Tool Calling)
java·人工智能·后端·python·spring·ai编程
编程大师哥3 小时前
匿名函数 lambda + 高阶函数
java·python·算法
vb2008114 小时前
FastAPI APIRouter
开发语言·python
会编程的土豆4 小时前
Go 语言反射(Reflection)详解
开发语言·后端·golang
adrninistrat0r4 小时前
Java调用链MCP分析工具
java·python·ai编程
喵个咪4 小时前
GoWind Toolkit Go后端代码生成 完整全流程实战
后端·go·orm
杨充4 小时前
1.3 浮点型数据设计灵魂
开发语言·python·算法
basketball6164 小时前
Go 语言从入门到进阶:4. 数组和MAP使用方法总结
开发语言·后端·golang