Python多进程、多线程及各⾃的适⽤场景
多线程与多进程的应⽤场景不⼀样:
1、线程的创建开销⼩、由于GIL的存在,⽆法真正并⾏,适合GUI、⽹络通信、⽂件读写等IO密集型场景;
2、进程的创建开销⼤,可以充分利⽤多个CPU实现并⾏,适合计算量⽐较⼤(⽐如单个函数执⾏需要⼏分钟、⼏⼗分钟以上),且⽆需IO(简单地说就是数据已经在内存中,不需要读取磁盘、不需要⽹络通信)的场景。
3、多线程、多进程都不适合的场景:基本不涉及IO或只读取⼀次⽂件这种,且计算量不⼤,单线程短时间就能结束(⼀两秒左右)的情况下,单进程单线程是最好的。
我⾃⼰做过对⽐实验,这种情况下单进程>多线程>>多进程,实际测试结果:单线程0.98s,4个线程1.03s,4个进程1.6s。
原因在于创建线程、进程的时间额外开销超过了任务本⾝的计算时间。
4、实现多线程的⽅式:threading.Thread()、线程池concurrent.futures.ThreadPoolExecutor
5、实现多进程的⽅式:multiprocessing.Process、进程池concurrent.futures.ProcessPoolExecutor
6、多线程实现互斥:lock=threading.Lock(),lock.acquire(),访问共享变量,lease(),
7、线程之间的数据共享:多个线程共⽤⼀个普通变量作为共享变量就可以,因为多线程共享同⼀个进程的内存空间。
一个线程可以包含多个进程8、多进程实现互斥:lock=multiprocessing.Manager().Lock();每个进程先lock.acquire(),然后访问共享变量,再lease()。
9、进程之间的数据共享:普通变量不能⽤作共享变量(因为普通变量属于宿主进程空间,不属于新创建的进程们,存在隔离),必须使⽤multiprocessing.Manager()提供的数据类型。
例如:
list_=Manager().list() #⽤类似Python的普通list,可以append,但不能直接取值,需要先⽤list(var)强制转为普通list
dic_=Manager().dict(), #类似普通的dict
v_=Manager().Value(typecode,value),#单个变量,typecode
array_=Manager().Array(typecode,sequence) #数组
10、进程之间数据共享的其他⽅式:pipe、queue

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。