台式机&硬件|什么是“进程、线程、协程”?( 四 )
无论是单核还是多核,一个进程永远只能同时执行一个线程(拿到 GIL 的线程才能执行 , 如下图所示) , 这就是为什么在多核CPU上 , Python 的多线程效率并不高的根本原因 。
本文插图
那是不是在Python中遇到并发的需求就使用多进程就万事大吉了呢?其实不然 , 软件工程中有一句名言:没有银弹!
2、何时用? 常见的应用场景不外乎三种:
- CPU密集型:程序需要占用CPU进行大量的运算和数据处理;
- I/O密集型:程序中需要频繁的进行I/O操作;例如网络中socket数据传输和读取等;
- CPU密集+I/O密集:以上两种的结合
下面主要解释一下I/O密集型的情况 。 与I/O设备交互 , 目前最常用的解决方案就是DMA 。
3、什么是DMA DMA(Direct Memory Access)是系统中的一个特殊设备 , 它可以协调完成内存到设备间的数据传输 , 中间过程不需要CPU介入 。
以文件写入为例:
- 进程p1发出数据写入磁盘文件的请求
- CPU处理写入请求 , 通过编程告诉DMA引擎数据在内存的位置 , 要写入数据的大小以及目标设备等信息
- CPU处理其他进程p2的请求 , DMA负责将内存数据写入到设备中
- DMA完成数据传输 , 中断CPU
- CPU从p2上下文切换到p1,继续执行p1
本文插图
Python多线程的表现(I/O密集型)
- 线程Thread0首先执行 , 线程Thread1等待(GIL的存在)
- Thread0收到I/O请求 , 将请求转发给DMA,DMA执行请求
- Thread1占用CPU资源 , 继续执行
本文插图
与进程的执行模式相似 , 弥补了GIL带来的不足 , 又由于线程的开销远远小于进程的开销 , 因此 , 在IO密集型场景中 , 多线程的性能更高
实践是检验真理的唯一标准 , 下面将针对I/O密集型场景进行测试 。
测试
- 执行代码
import multiprocessing
import threading
import time
def count(num):
time.sleep(1) ## 模拟IO操作
print("Process {0} End".format(num))
if __name__ == "__main__":
start_time = time.time
process = list
for i in range(5):
p = multiprocessing.Process(target=count, args=(i,))
# p = threading.Thread(target=count, args=(i,))
process.append(p)
for p in process:
p.start
for p in process:
p.join
end_time = time.time
print("Total time:{0}".format(end_time - start_time))
- 结果
## 多进程Process 0 EndProcess 3 EndProcess 4 EndProcess 2 EndProcess 1 EndTotal time:1.383193016052246## 多线程Process 0 EndProcess 4 EndProcess 3 EndProcess 1 EndProcess 2 EndTotal time:1.003425121307373
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 智能穿戴|漫步者DreamPods体验:外观精致佩戴舒适降噪是最大惊喜
- 苹果手机,5G手机|苹果也堆硬件?iPhone12配置惊人,安卓将迎来最大挑战
- 苹果手机|苹果也堆硬件?iPhone12配置惊人,安卓将迎来最大挑战
- 中年|希柔专注女性消费市场,助力品牌"C位出道"
- 行业互联网|融创文旅与QG电子竞技俱乐部战略合作,开启"文旅+电竞"新航道
- APP|合规进行时丨关于 “APP & SDK 合规”你应该知道的那些事(第一弹)
- 数字化|腾讯云启&德勤中国强强联合,助力中小企业数字化转型
- 行业互联网|同盾&华为联合亮相中国高速公路信息化大会
- |极速鲨课堂37:主板的灯效会影响散热么?
- 行业互联网,阿里巴巴|新批发助推经济内循环 1688"千星计划"促产业带中小企业在线交易倍增