IO密集型任务 VS 计算密集型任务所谓IO密集型任务,是指磁盘IO、网络IO占主要的任务,计算量很小。比如请求网页、读写文件等。当然我们在Python中可以利用sleep达到IO密集型任务的目的。

所谓计算密集型任务,是指CPU计算占主要的任务,CPU一直处于满负荷状态。比如在一个很大的列表中查找元素(当然这不合理),复杂的加减乘除等。

多线程 VS 多进程Python中比较常见的并发方式主要有两种:多线程和多进程。当然还有协程,这里不做介绍。

1、多线程多线程即在一个进程中启动多个线程执行任务。一般来说使用多线程可以达到并行的目的,但由于Python中使用了全局解释锁GIL的概念,导致Python中的多线程并不是并行执行,而是“交替执行”。类似于下图:(图片转自网络,侵删)

所以Python中的多线程适合IO密集型任务,而不适合计算密集型任务。

Python提供两组多线程接口,一是thread模块_thread,提供低等级接口。二是threading模块,提供更容易使用的基于对象的接口,可以继承Thread对象来实现线程,此外其还提供了其它线程相关的对象,例如Timer,Lock等。

2、多进程由于Python中GIL的原因,对于计算密集型任务,Python下比较好的并行方式是使用多进程,这样可以非常有效的使用CPU资源。当然同一时间执行的进程数量取决你电脑的CPU核心数。

Python中的进程模块为mutliprocess模块,提供了很多容易使用的基于对象的接口。另外它提供了封装好的管道和队列,可以方便的在进程间传递消息。Python还提供了进程池Pool对象,可以方便的管理和控制线程。

实例讲解Python中的多线程、多进程如何应对IO密集型任务、计算密集型任务本文不会讲解Python多线程模块、多进程模块的具体用法,想了解的可以参考官方文档。这里通过一个实例,说明多线程适合IO密集型任务,多进程适合计算密集型任务。

首先定义一个队列,并定义初始化队列的函数:

# 定义全局变量Queue

g_queue = multiprocessing.Queue()

def init_queue():

print("init g_queue start")

while not g_queue.empty():

g_queue.get()

for _index in range(10):

g_queue.put(_index)

print("init g_queue end")

return

然后定义IO密集型任务和计算密集型任务,分别从队列中获取任务数据:

# 定义一个IO密集型任务:利用time.sleep()

def task_io(task_id):

print("IOTask[%s] start" % task_id)

while not g_queue.empty():

time.sleep(1)

try:

data = g_queue.get(block=True, timeout=1)

print("IOTask[%s] get data:%s" % (task_id, data))

except Exception as excep:

print("IOTask[%s] error:%s" % (task_id, str(excep)))

print("IOTask[%s] end" % task_id)

return

g_search_list = list(range(10000))

# 定义一个计算密集型任务:利用一些复杂加减乘除、列表查找等

def task_cpu(task_id):

print("CPUTask[%s] start" % task_id)

while not g_queue.empty():

count = 0

for i in range(10000):

count += pow(3*2, 3*2) if i in g_search_list else 0

try:

data = g_queue.get(block=True, timeout=1)

print("CPUTask[%s] get data:%s" % (task_id, data))

except Exception as excep:

print("CPUTask[%s] error:%s" % (task_id, str(excep)))

print("CPUTask[%s] end" % task_id)

return task_id

准备完上述代码之后,进行试验:

if __name__ == '__main__':

print("cpu count:", multiprocessing.cpu_count(), "\n")

print("========== 直接执行IO密集型任务 ==========")

init_queue()

time_0 = time.time()

task_io(0)

print("结束:", time.time() - time_0, "\n")

print("========== 多线程执行IO密集型任务 ==========")

init_queue()

time_0 = time.time()

thread_list = [threading.Thread(target=task_io, args=(i,)) for i in range(5)]

for t in thread_list:

t.start()

for t in thread_list:

if t.is_alive():

t.join()

print("结束:", time.time() - time_0, "\n")

print("========== 多进程执行IO密集型任务 ==========")

init_queue()

time_0 = time.time()

process_list = [multiprocessing.Process(target=task_io, args=(i,)) for i in range(multiprocessing.cpu_count())]

for p in process_list:

p.start()

for p in process_list:

if p.is_alive():

p.join()

print("结束:", time.time() - time_0, "\n")

print("========== 直接执行CPU密集型任务 ==========")

init_queue()

time_0 = time.time()

task_cpu(0)

print("结束:", time.time() - time_0, "\n")

print("========== 多线程执行CPU密集型任务 ==========")

init_queue()

time_0 = time.time()

thread_list = [threading.Thread(target=task_cpu, args=(i,)) for i in range(5)]

for t in thread_list:

t.start()

for t in thread_list:

if t.is_alive():

t.join()

print("结束:", time.time() - time_0, "\n")

print("========== 多进程执行cpu密集型任务 ==========")

init_queue()

time_0 = time.time()

process_list = [multiprocessing.Process(target=task_cpu, args=(i,)) for i in range(multiprocessing.cpu_count())]

for p in process_list:

p.start()

for p in process_list:

if p.is_alive():

p.join()

print("结束:", time.time() - time_0, "\n")

结果说明:

对于IO密集型任务:直接执行用时:10.0333秒

多线程执行用时:4.0156秒

多进程执行用时:5.0182秒

说明多线程适合IO密集型任务。

对于计算密集型任务

直接执行用时:10.0273秒

多线程执行用时:13.247秒

多进程执行用时:6.8377秒

说明多进程适合计算密集型任务

=============================================================

欢迎大家拍砖、提意见。相互交流,共同进步!

==============================================================

python io密集 多线程_Python进阶:聊聊IO密集型任务、计算密集型任务,以及多线程、多进程...相关推荐

  1. python 协程 多线程_python进阶之多线程(简单介绍协程)

    多线程 线程:实现多任务的另一种方式 一个进程中,也经常需要同时做多件事,就需要同时运行多个'子任务',这些子任务,就是线程 线程又被称为轻量级进程(lightweight process),是更小的 ...

  2. python epoll多路复用技术_python网络编程——IO多路复用之epoll

    1.内核EPOLL模型讲解 此部分参考http://blog.csdn.net/mango_song/article/details/42643971博文并整理 首先我们来定义流的概念,一个流可以是文 ...

  3. python控制结束多线程_python进阶八——并发编程之多线程

    1:线程介绍 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程 车间负责把资源整合到 ...

  4. python bytes查找位置_Python进阶5---StringIO和BytesIO、路径操作、OS模块、shutil模块

    StringIO StringIO操作 BytesIO BytesIO操作 file-like对象 路径操作 路径操作模块 3.4版本之前:os.path模块 3.4版本开始 建议使用pathlib模 ...

  5. python模块编程教程_python进阶教程之模块(module)介绍

    我们之前看到了函数和对象.从本质上来说,它们都是为了更好的组织已经有的程序,以方便重复利用. 模块(module)也是为了同样的目的.在Python中,一个.py文件就构成一个模块.通过模块,你可以调 ...

  6. python socket udp并发_Python进阶----UDP协议使用socket通信,socketserver模块实现并发

    Python进阶----UDP协议使用socket通信,socketserver模块实现并发 一丶基于UDP协议的socket 实现UDP协议传输数据 代码如下:

  7. python 有趣的变量_Python进阶之路 3.2有趣的赋值操作

    3.2 有趣的赋值操作 赋值操作是再简单不过了,在前面的章节也多次使用了赋值操作.不过Python语言中的赋值操作要有趣得多.例如,可以同时将多个值赋给多个变量. x,y,z = 1,2,3 prin ...

  8. python字典高级用法_Python 进阶编程之字典的高级用法

    一. collections 中 defaultdict 的使用 1.1 字典的键映射多个值 将下面的列表转成字典 l = [('a',2),('b',3),('a',1),('b',4),('a', ...

  9. python申请内存函数_python进阶用法2 【从帮助函数看python内存申请机制】

    前言 介绍了四个帮助函数,dir(),help(),type(),id(),通过id()函数进一步分析了python在申请内存方面的效率问题,提到的基本类型有string,list,queue和deq ...

最新文章

  1. 《自然》:欧洲根据已知基因序列合成新冠病毒,助力疫苗开发
  2. SuperSocket 1.5 Documentation译文 2 ----- 实现你的AppServer和AppSession
  3. 简介(CAB和SCSF编程)
  4. Python 3.9,来了!
  5. Windows服务器上配置环境,并上传Django项目流程记录
  6. Xuggler教程:帧捕获和视频创建
  7. mysql jdbc linux,linux mysql jdbc 权限问题_MySQL
  8. MEncoder的基础用法—6.3. 编码为双通道MPEG-4 (DivX)
  9. 阶段3 2.Spring_06.Spring的新注解_6 Qualifier注解的另一种用法
  10. FLV文件格式官方规范详解
  11. dell服务器怎么看故障信息,DELL服务器故障码详解
  12. 云计算-平台架构-开源-OpenStack
  13. WPS表格(Excel)常用函数与技巧总结
  14. 芯动科技面试——数字IC/FPGA面试案例总结1
  15. ZROI 2018 ZYB和售货机(goods)
  16. CSP-J1 CSP-S2第1轮 初赛资料集(2022.09.09)
  17. 【PHP小皮】使用教程
  18. Loadrunner11.00破解方法
  19. vulnhub靶场-Hacker_Kid-v1.0.1
  20. Linux 安装Oracel18C完整版

热门文章

  1. 【干货】你常用的5种地图数据汇总对比,值得收藏~
  2. tfcenter支持DDNS端口映射Webdav服务,不需担心家庭网络出口公网IPv4发生变化导致网络中断
  3. python余数不等于的符号_有乐 这些符号如此重要,不知道就等于“白练琴”
  4. 零费用学习网络营销,小伙伴们惊呆了
  5. 卡尔·古斯塔夫· 荣格
  6. 马云号召快递公司提升员工待遇:快递员带回家的钱要让家人惊喜
  7. sqlserver用sql语句来进行外键约束的修改
  8. 简单获取unix时间戳
  9. 给孩子积极心理暗示的语句实操
  10. 功率器件-功率晶体管 GTR