聊聊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。

相关推荐
颜酱几秒前
一栋商业大厦,讲清 InnoDB 的表空间、段、区和页
后端·mysql
snhna6 分钟前
DeerFlow 2.x 源码拆解:多智能体委派、Skills、沙箱与 Linux 部署实战
人工智能·python
码事漫谈10 分钟前
1956 亿行数据该怎么存:金仓时序数据库的三个实测
后端
Wx-bishekaifayuan14 分钟前
springboot桂味美食分享系统40540-计算机课程设计、毕业设计
spring boot·后端·python·django·课程设计·express·旅游
Metaphor69227 分钟前
如何快速拆分超大 Excel 文件【Python 教程】
python·excel
彭亚川Allen30 分钟前
从零手搓 RAG 之检索全流程,给大模型接上自己的知识库
前端·后端·ai编程
IT_陈寒32 分钟前
别让Java字符串拼接偷偷吃掉你的内存
前端·人工智能·后端
_Evan_Yao37 分钟前
前后端联调怎么排查问题?从 Network 到后端日志,一步步定位错误
开发语言·后端·团队开发·需求分析
孟健1 小时前
从单体失控到解耦管道:用 Unix 哲学重构 Anthropic 式多 Agent 动态工作流
人工智能·python·架构
小白快快跑哦1 小时前
python-字符串全解(六):正则表达式-前后相断言
开发语言·python·正则表达式·前后相断言