如果有一大批数据,需要根据一定的逻辑完成数据处理,你可能会有如下几种情况:
- 不引入并发,编写的脚本执行效率很低
- 想要引入并发,但是不会用
- 学过多进程、多线程和多协程,但是不知道当下这种情况该选哪种
下面我们就来做一下探讨!
一、选型问题
- 进程
1、首先,如果线程、协程都解决不了你的问题,则考虑一下使用进程(进程开销大,所以优先考虑线程、协程)
2、其次,需要确认你程序要运行的机器的cpu的核数,linux可以使用命令cat /proc/cpuinfo |grep "processor"|sort -u|wc -l
查看。如果你的cpu核数较为理想(需要同时考虑其他程序的进程的占用而确定,比如运行在这台机器上的一些软件什么的),且你可以搞定进程间通信,可以选择进程。
3、当然,如果你的cpu只有一个核,这意味着同一时间只能有一个进程在占用cpu,则选择多进程完全不会有任何提效。 - 线程
1、如果想要使用线程,就不得不对python解释器CPython的底层GIL有一定的了解
2、其次,分析一下你的业务场景中IO操作(如文件读写、网络传输)的占比。如果IO操作不多(即CPU密集型)的话,python的多线程不是一个好的选择,因为这意味着各线程都要占用cpu,但是GIL决定了同一时间只能有一个线程占用cpu,所以针对IO操作较多(即IO密集型)的程序,多线程或许是你的一个比较好的选择,因为多线程相对编码容易,且IO多就促成了cpu可以空出时间去做其他的事情,效率自然也就提高了。
3、当然,使用多线程时并非线程数越多越快,因为系统切换线程也存在较大的开销,开发者应尽可能找到最佳的临界点,以最大化执行效率。 - 协程
1、对比多进程,协程开销小且不需要考虑同步问题
2、针对IO密集型程序,并发数量较多的情况下,可能比多线程效率要高,对比线程数越多的多线程程序协程的优势就越明显(由于GIL的限制,多线程主要是败在了线程切换的开销,线程数越多,开销越大);针对CPU密集型程序,无优势。
3、协程是异步的,当遇到IO操作,会中断转而去处理其他任务,等IO结束返回来继续处理。 - 多进程+协程
如果cpu够用,可考虑多进程+协程结合使用。既充分利用了多核,又发挥了协程的高效率,可获得极高的性能。
总的来说,CPU密集型选多进程,IO密集型看线程并发量斟酌选多线程或协程,想发挥出多核cpu最大优势,选多进程+协程。
二、demo
1、多进程
待补充
2、多线程
import threading
from math import ceil
def test(data, threadNums):
num = len(data)
n = int(threading.currentThread().getName())
# 避免不能整除
count = ceil(num / threadNums)
for i in range(n * count, (n + 1) * count):
# 不能越界
if i < num:
print(data[i]) # 这里替换为业务逻辑
# data为数据列表(或字典等其他类型,根据实际业务情况而定),threadNum为线程数
def testThread(data, threadNum):
threadList = []
for i in range(threadNum):
thread = threading.Thread(target=test, args=(data, threadNum), name="{}".format(i))
thread.start()
threadList.append(thread)
for j in threadList:
j.join()
if __name__ == '__main__':
testThread([i for i in range(10)], 3)
3、多协程
待补充
4、多进程+协程
待补充
END~
参考:
廖雪峰的官方网站
python中的GIL详解
浅析Python的进程、线程与协程
【python】python进程、线程、协程和什么时候使用