前言

在Python中,计算密集型任务适用于多进程,IO密集型任务适用于多线程

 

正常来讲,多线程要比多进程效率更高,因为进程间的切换需要的资源和开销更大,而线程相对更小,但是我们使用的Python大多数的解释器是Cpython,众所周知Cpython有个GIL锁,导致执行计算密集型任务时多线程实际只能是单线程,而且由于线程之间切换的开销导致多线程往往比实际的单线程还要慢,所以在 python 中计算密集型任务通常使用多进程,因为各个进程有各自独立的GIL,互不干扰。

 

而在IO密集型任务中,CPU时常处于等待状态,操作系统需要频繁与外界环境进行交互,如读写文件,在网络间通信等。在这期间GIL会被释放,因而就可以使用真正的多线程。

 

上面都是理论,接下来实战看看实际效果是否符合理论

练习

"""多线程多进程模拟执行效率"""

from multiprocessing import Pool
from threading import Thread
import time, math def simulation_IO(a):
"""模拟IO操作"""
time.sleep(3) def simulation_compute(a):
"""模拟计算密集型任务"""
for i in range(int(1e7)):
math.sin(40) + math.cos(40)
return def normal_func(func):
"""普通方法执行效率"""
for i in range(6):
func(i)
return def mp(func):
"""进程池中的map方法"""
with Pool(processes=6) as p:
res = p.map(func, list(range(6)))
return def asy(func):
"""进程池中的异步执行"""
with Pool(processes=6) as p:
result = []
for j in range(6):
a = p.apply_async(func, args=(j, ))
result.append(a)
res = [j.get() for j in result] def thread(func):
"""多线程方法"""
threads = []
for j in range(6):
t = Thread(target=func, args=(j, ))
threads.append(t)
t.start()
for t in threads:
t.join() def showtime(f, func, name):
"""
计算并展示函数的运行时间
:param f: 多进程和多线程的方法
:param func: 多进程和多线程方法中需要传入的函数
:param name: 方法的名字
:return:
"""
start_time = time.time()
f(func)
print(f"{name} time: {time.time() - start_time:.4f}s") def main(func):
"""
运行程序的主函数
:param func: 传入需要计算时间的函数名
"""
showtime(normal_func, func, "normal")
print()
print("------ 多进程 ------")
showtime(mp, func, "map")
showtime(asy, func, "async")
print()
print("----- 多线程 -----")
showtime(thread, func, "thread") if __name__ == "__main__":
print("------------ 计算密集型 ------------")
func = simulation_compute
main(func)
print()
print()
print()
print("------------ IO 密集型 ------------")
func = simulation_IO
main(func)

结果

线性执行 多进程(map) 多进程(async) 多线程
计算密集型 16.0284s 3.5236s 3.4367s 15.2142s
IO密集型 18.0201s 3.0945s 3.0809s 3.0041s

结论

从表格中很明显的可以看出:

  • 计算密集型任务的速度:多进程 >多线程> 单进程/线程
  • IO密集型任务速度: 多线程 > 多进程 > 单进程/线程。

所以,针对计算密集型任务使用多进程,针对IO密集型任务使用多线程

python进阶(15)多线程与多进程效率测试的更多相关文章

  1. Python进阶:多线程、多进程和线程池编程/协程和异步io/asyncio并发编程

    gil: gil使得同一个时刻只有一个线程在一个CPU上执行字节码,无法将多个线程映射到多个CPU上执行 gil会根据执行的字节码行数以及时间片释放gil,gil在遇到io的操作时候主动释放 thre ...

  2. python分别使用多线程和多进程获取所有股票实时数据

    python分别使用多线程和多进程获取所有股票实时数据   前一天简单介绍了python怎样获取历史数据和实时分笔数据,那么如果要获取所有上市公司的实时分笔数据,应该怎么做呢? 肯定有人想的是,用一个 ...

  3. python爬虫之多线程、多进程+代码示例

    python爬虫之多线程.多进程 使用多进程.多线程编写爬虫的代码能有效的提高爬虫爬取目标网站的效率. 一.什么是进程和线程 引用廖雪峰的官方网站关于进程和线程的讲解: 进程:对于操作系统来说,一个任 ...

  4. 第十章:Python高级编程-多线程、多进程和线程池编程

    第十章:Python高级编程-多线程.多进程和线程池编程 Python3高级核心技术97讲 笔记 目录 第十章:Python高级编程-多线程.多进程和线程池编程 10.1 Python中的GIL 10 ...

  5. python中的多线程和多进程

    一.简单理解一下线程和进程 一个进程中可有多个线程,线程之间可共享内存,进程间却是相互独立的.打比方就是,进程是火车,线程是火车厢,车厢内人员可以流动(数据共享) 二.python中的多线程和多进程 ...

  6. Python之threading多线程,多进程

    1.threading模块是Python里面常用的线程模块,多线程处理任务对于提升效率非常重要,先说一下线程和进程的各种区别,如图 概括起来就是 IO密集型(不用CPU) 多线程计算密集型(用CPU) ...

  7. Python系列之多线程、多进程

    线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix Thread,而不是模拟出来的线程. Python的标准库提供 ...

  8. python爬虫之多线程、多进程、GIL锁

    背景: 我们知道多线程要比多进程效率更高,因为线程存在于进程之内,打开一个进程的话,首先需要开辟内存空间,占用内存空间比线程大.这样想也不怪,比如一个进程用10MB,开10个进程就得100MB的内存空 ...

  9. python之路-----多线程与多进程

    一.进程和线程的概念 1.进程(最小的资源单位): 进程:就是一个程序在一个数据集上的一次动态执行过程.进程一般由程序.数据集.进程控制块三部分组成. 程序:我们编写的程序用来描述进程要完成哪些功能以 ...

随机推荐

  1. 学习一下 SpringCloud (五)-- 配置中心 Config、消息总线 Bus、链路追踪 Sleuth、配置中心 Nacos

    (1) 相关博文地址: 学习一下 SpringCloud (一)-- 从单体架构到微服务架构.代码拆分(maven 聚合): https://www.cnblogs.com/l-y-h/p/14105 ...

  2. 多Excel文件内容查询工具。

    多Excel文件内容查询工具. 告别繁琐重复的体力劳动,一分钟干完一天的活. 码云 github 下载 当需要在多个Excel表格中查询需要的信息是,一个文件一个文件的去查询非常麻烦. 虽然有其他方法 ...

  3. docker封装Spring Cloud(单机版)

    一.概述 微服务统一在一个git项目里面,项目的大致结构如下: ./ ├── auth-server │ ├── pom.xml │ └── src ├── common │ ├── pom.xml ...

  4. ios打包的IDP证书的创建方法

    在我们打包ios应用的时候,需要一个IDP证书. 那么我们如何生成这个IDP证书呢?网上介绍的方法都是需要使用mac电脑,然后用mac电脑的钥匙串访问的功能先生成csr文件,然后去苹果开发者生成,然而 ...

  5. 2020年HTML5考试模拟题整理(一)

    1.哪个元素被称为媒体元素的子元素? 答案:<track>. <track> 标签为媒体元素(比如 <audio> and <video>)规定外部文本 ...

  6. 初窥MyBatis-普通的CRUD操作

    编写接口 编写对应的Mapper.xml中的sql语句 测试(增删改需要提交事务) <mapper namespace="com.perwrj.dao.UserMapper" ...

  7. STM32 ADC详细篇(基于HAL库)

    一.基础认识 ADC就是模数转换,即将模拟量转换为数字量 l  分辨率,读出的数据的长度,如8位就是最大值为255的意思,即范围[0,255],12位就是最大值为4096,即范围[0,4096] l  ...

  8. c++ 11 是如何简化你的数据库访问接口的

    之前写过一篇文章专门分析了 c++ 模板编译过程中报的一个错误:<fatal error C1045: 编译器限制 : 链接规范嵌套太深 >,其中涉及到了 qtl -- 一个使用 c++ ...

  9. WPF 基础 - 图片之界面截图

    1. 功能 系统截图. 2. 实现 2.1 思路 控件继承自 System.Windows.Media.Visual, 通过 System.Windows.Media.Imaging.RenderVi ...

  10. C# 基础 - Environment 类

    1. 程序根目录: (D:\\...\\WpfApp1\\WpfApp1\\bin\\Debug") string exePath = Environment.CurrentDirector ...