python多进程与多线程使用
简介
关于多进程和多线程的详细介绍参考其他资料,这里仅列出一些显著特征,用于帮助实际使用时选择哪种方法。
多线程
- 多线程之间共享内存和变量;
- 创建线程总体资源消耗较低;
- 由于GIL锁,只能使用单核,性能一般较低,特殊情况甚至低于串行;
- 适用于I/O密集型任务,比如大量文件读写,网络请求(文件下载)等;
多进程
- 进程间无法直接共享内存,需要使用其他方法,否则内存消耗巨大;
- 创建进程总体资源消耗较高;
- 完全并发执行,效率高;
- 适用于计算密集型,充分利用多核CPU;
常用模块
以下以多进程为例。
multiprocessing
- 手动创建进程Process
def download(url):res = requests.get(url)return resprocesses = []
for url in urls:processes.append(Process(target = download,args=(url)))
for i in processes:i.start() #运行进程
for i in pool_down:i.join() # 等待进程结束,返回结果
等进程较多或任务较多时,频繁创建进程,销毁进程并不必要,此时可以使用进程池。
- 进程池Pool
result = []
iters = [args for args in args_list]
# 可开启指定数目的进程池,当进程池中某个任务完成后,下一个任务会继续进入进程池中运行
with Pool(6) as p:#使用tqdm,可显示进度条,表明已完成的任务数目with tqdm(total=len(iters),desc="processing") as pbar:for i, res in enumerate(p.imap(func, iters)): result .append(res)
进程池常用运行方法:
- apply,返回结果前阻塞进程;
- apply_async,异步执行,不阻塞进程;
- imap,通过迭代器获取返回结果;
- imap_unordered,与imap相同,但是结果是无序的;
- 进程间共享对象
由于多进程相互隔离,每个进程都会把用到的数据复制一份,导致内存使用消耗巨大。因此在进程间共享对象可有效降低内存使用,在资源有限的情况有效提高多进程的实用性。具体方式有以下几种:
(1)共享内存
可使用Value 和Array,或RawValue和 RawArray类型,其中前两个是加锁的,保证进程安全,后两个是不加锁的,根据实际情况使用可提升效率,比如对于只读数据,可以使用Raw类型。直接传参可能报错,此时需要通过在Pool启动时的initializer 中传参数。
但是支持的类型有限,不够灵活。
(2)Manager服务进程
Manager对象会创建一个进程,其中保存共享对象,供其他进程访问使用。支
持的类型非常丰富,包括:list,dict等。
但是添加数据非常缓慢耗时,经测试,创建 Manager().dict() 并添加数据,耗时比普通dict用时增加百倍以上。对此,可使用以下方法,先建立普通dict,然后再更新到Manager().dict中。
data = Manager().dict()dict_tmp = {"key1":"value1","key2":"value2",...}data.update(dict_tmp ) #插入数据data.clear() # 清除数据
(3) shared_memory
python 3.8 以上提供了新的对象, multiprocessing.shared_memory ,暂未使用,待研究。
- 启动多进程
- spawn
- fork
- forkserver
需要在 name == ‘__ main__’ 之后设置,且一个程序中仅设置一次即可。如 :
set_start_method(“spawn”)
concurrent.futures
concurrent.futures 模块是更高层次封装的接口,使得并发和并行的代码更加简单。速度上似乎差别不大,未有详细测试过。
简单使用如下:
with ProcessPoolExecutor(max_workers=6) as executor:future = executor.submit(func, (args,))
常见问题及解决
- IndexError: pop from an empty deque
多进程无法启动,需要设置set_start_method() - cannot pickle ‘SSLSocket’ object
多进程拷贝数据时对象无法序列化。需要仔细查看对象属性和方法,对应修改。 - 已知multiprocessing多进程 某些时候存在无法退出进程的情况
python多进程与多线程使用相关推荐
- 一文看懂Python多进程与多线程编程(工作学习面试必读)
进程(process)和线程(thread)是非常抽象的概念, 也是程序员必需掌握的核心知识.多进程和多线程编程对于代码的并发执行,提升代码效率和缩短运行时间至关重要.小编我今天就来尝试下用一文总结下 ...
- python 多进程和多线程
python 多进程和多线程 一.进程和线程 1.概念 进程: 一个进程就是一个任务,可以理解为一个程序.一个进程可以有多个线程,至少一个.多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影 ...
- 【干货】python多进程和多线程谁更快
python多进程和多线程谁更快 python3.6 threading和multiprocessing 自从用多进程和多线程进行编程,一致没搞懂到底谁更快.网上很多都说python多进程更快,因为G ...
- Python多进程和多线程的使用场景
Python多进程适用的场景:计算密集型(CPU密集型)任务 Python多线程适用的场景:IO密集型任务 计算密集型任务一般指需要做大量的逻辑运算,比如上亿次的加减乘除,使用多核CPU可以并发提高计 ...
- python多进程和多线程看这一篇就够了
脑海中关于进程和线程的概念一直很模糊,什么时候该用多进程,什么时候该用多线程总是搞不清楚.同时python因为历史遗留问题存在GIL全局锁,就让人更加困惑.这一篇就完整整理一下python中进程和线程 ...
- python多进程和多线程一起使用_Python干货:多进程与多线程!
今天我们来聊聊Python里面的多进程与多线程编程模式. 01 多线程工作 在开始讲今天的正文之前,先给大家介绍一个概念「多线程工作」,这个概念可能有的人听过,也可能有的人平常工作中就是这么做的.我再 ...
- python多进程、多线程
1.python多线程 使用一个例子来学习多线程.建议自己敲一遍. python多线程是通过threading模块的Thread实现. 创建线程对象 t = thread.Thread() 启动线程 ...
- Python多进程、多线程编程
文章目录 1. 进程.线程.协程 2. Python多线程 GIL全局解释器锁 CPython科普 3. Python:多进程 or 多线程 计算密集型.I/O密集型科普 4. 编程实战 1. 进程. ...
- Python 多进程、多线程启动
本文仅供学习交流使用,如侵立删!demo下载见文末 Python 多进程启动 def main(self, num):"""多进程启动ValueError: Pool n ...
最新文章
- 使用LINUX SENDMAIL发送邮件
- JVM调优总结(2):一些概念(下)
- outlook html阅读,Html Email 邮件html页编写指南
- 重构机房收费系统(一)
- ucinet使用手册_ucinet使用手册
- _技巧_Chrome_Vimium插件_纯键盘控制浏览器
- 走不远的共享滑板车!
- tomcat并发优化
- 初识Hibernate的主配置和映射配置
- 二分排序(java)
- H3C新华三笔记本FN键锁定
- 【Java 8 新特性】Java CompletableFuture thenApply()
- Element-UI 图标乱码解决方案
- 图像算法工程师需要这样
- 软考证书可积分落户、评职称、抵扣个税等,快来考一个吧!
- Postgresql杂谈 16—Postgresql中的锁机制
- 字符串的定义与赋值及初始化
- linux批量卸载rpm,shell实现rpm -e 一键卸载所有相关包以及依赖
- Chosen by god
- 拿来就用的脚本案例(三)
热门文章
- 软件手工测试和自动化测试比不同!!
- 线性回归的PyTorch实现
- java核酸检测异常处理
- 蓝桥杯备赛 | 官方题库基础练习(含VIP试题)试题+答案(共33题)
- 软工实践第七次作业——需求分析报告
- 系统win11 磁盘锁解除
- thinkcmf index.php,ThinkCMF应用开发流程
- Java 工具(jmap,jstack)在linux上的源码分析(四)safe point
- 金蝶标准版迷你版 数据库引擎找不到对象MSysDb。请确定对象是否存在,并正确的写出他的名称和路径 帐套损坏。
- WiFi6模组RW6852S-50