并发编程—进程、线程、协程的区别
1、资源
进程:计算机最小的资源单位
线程:进程内开启,资源消耗远小于进程,开启时间也远小于进程
协程:线程内开启,资源消耗小于线程,开启时间也小于线程
2、效率
2.1 cpu执行效率:
1、cpu可以做计算和I/O
2、多核cpu可以同时进行计算,能够有效的提升计算效率
3、cpu遇到I/O时,肯定会让线程进入阻塞态,就算是多核,也仍需等待,所以多核不能提升I/O速率
即:对计算来说,cpu越多越好,但是对于I/O来说,再多的CPU也没用
基于此,进程、线程、协程的效率也要分I/O密集还是计算密集来看
2.2 计算密集型
计算密集型
由于计算操作较多,所以程序的执行效率取决于CPU的计算性能
单核:都是并发执行,并且I/O操作较少,所以执行效率时相差不多的,相差的执行时间基本上就是开启进程与开启线程的差别
多核:由于多进程可以实现并行,所以当任务越多,多核在计算性能上的提升越明显
2.3 I/O密集型
I/O密集型
由于I/O操作较多,所以程序的执行速率取决于CPU的I/O性能
单核:多进程也只能实现并发,此时,多线程与多进程的差别,只有在遇到I/O时切换的效率差别了,很明显,多线程的效率要高的多
多核:CPU在遇到I/O操作时,必须等待I/O,因此多核多I/O的性能提升不大,此时多线程与多进程的差别,也取决于遇到I/O是的切换效率了,很明显,当任务量越多,多线程的效率越高
3、代码
3.1 多线程与多进程
代码演示
计算密集型
from multiprocessing import Process
from threading import Thread
import time,os
def work():
res = 0
for i in range(100000000):
res += 1
print(res)
if __name__ == '__main__':
l = []
print(os.cpu_count())
start_time = time.time()
for i in range(1):
p = Process(target=work)
# p = Thread(target=work)
l.append(p)
p.start()
for p in l:
p.join()
stop_time = time.time()
print(f'消耗时间:{stop_time-start_time}')
I/O密集型
from multiprocessing import Process
from threading import Thread
import time,os
def work(i):
time.sleep(0.1)
print(i)
if __name__ == '__main__':
l = []
print(os.cpu_count())
start_time = time.time()
for i in range(100):
p = Process(target=work,args=(i,))
# p = Thread(target=work,args=(i,))
l.append(p)
p.start()
for p in l:
p.join()
stop_time = time.time()
print(f'消耗时间:{stop_time-start_time}')