python io密集 多线程_Python进阶:聊聊IO密集型任务、计算密集型任务,以及多线程、多进程...
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密集型任务、计算密集型任务,以及多线程、多进程...相关推荐
- python 协程 多线程_python进阶之多线程(简单介绍协程)
多线程 线程:实现多任务的另一种方式 一个进程中,也经常需要同时做多件事,就需要同时运行多个'子任务',这些子任务,就是线程 线程又被称为轻量级进程(lightweight process),是更小的 ...
- python epoll多路复用技术_python网络编程——IO多路复用之epoll
1.内核EPOLL模型讲解 此部分参考http://blog.csdn.net/mango_song/article/details/42643971博文并整理 首先我们来定义流的概念,一个流可以是文 ...
- python控制结束多线程_python进阶八——并发编程之多线程
1:线程介绍 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程 车间负责把资源整合到 ...
- python bytes查找位置_Python进阶5---StringIO和BytesIO、路径操作、OS模块、shutil模块
StringIO StringIO操作 BytesIO BytesIO操作 file-like对象 路径操作 路径操作模块 3.4版本之前:os.path模块 3.4版本开始 建议使用pathlib模 ...
- python模块编程教程_python进阶教程之模块(module)介绍
我们之前看到了函数和对象.从本质上来说,它们都是为了更好的组织已经有的程序,以方便重复利用. 模块(module)也是为了同样的目的.在Python中,一个.py文件就构成一个模块.通过模块,你可以调 ...
- python socket udp并发_Python进阶----UDP协议使用socket通信,socketserver模块实现并发
Python进阶----UDP协议使用socket通信,socketserver模块实现并发 一丶基于UDP协议的socket 实现UDP协议传输数据 代码如下:
- python 有趣的变量_Python进阶之路 3.2有趣的赋值操作
3.2 有趣的赋值操作 赋值操作是再简单不过了,在前面的章节也多次使用了赋值操作.不过Python语言中的赋值操作要有趣得多.例如,可以同时将多个值赋给多个变量. x,y,z = 1,2,3 prin ...
- python字典高级用法_Python 进阶编程之字典的高级用法
一. collections 中 defaultdict 的使用 1.1 字典的键映射多个值 将下面的列表转成字典 l = [('a',2),('b',3),('a',1),('b',4),('a', ...
- python申请内存函数_python进阶用法2 【从帮助函数看python内存申请机制】
前言 介绍了四个帮助函数,dir(),help(),type(),id(),通过id()函数进一步分析了python在申请内存方面的效率问题,提到的基本类型有string,list,queue和deq ...
最新文章
- 《自然》:欧洲根据已知基因序列合成新冠病毒,助力疫苗开发
- SuperSocket 1.5 Documentation译文 2 ----- 实现你的AppServer和AppSession
- 简介(CAB和SCSF编程)
- Python 3.9,来了!
- Windows服务器上配置环境,并上传Django项目流程记录
- Xuggler教程:帧捕获和视频创建
- mysql jdbc linux,linux mysql jdbc 权限问题_MySQL
- MEncoder的基础用法—6.3. 编码为双通道MPEG-4 (DivX)
- 阶段3 2.Spring_06.Spring的新注解_6 Qualifier注解的另一种用法
- FLV文件格式官方规范详解
- dell服务器怎么看故障信息,DELL服务器故障码详解
- 云计算-平台架构-开源-OpenStack
- WPS表格(Excel)常用函数与技巧总结
- 芯动科技面试——数字IC/FPGA面试案例总结1
- ZROI 2018 ZYB和售货机(goods)
- CSP-J1 CSP-S2第1轮 初赛资料集(2022.09.09)
- 【PHP小皮】使用教程
- Loadrunner11.00破解方法
- vulnhub靶场-Hacker_Kid-v1.0.1
- Linux 安装Oracel18C完整版