进程:是计算机中资源分配的最小单位
线程:是计算机中cpu调度的最小单位
1 pid考虑
多进程的时候每个子进程有自己的pid
多个线程共享一个进程pid
2 数据隔离和共享
多进程之间数据隔离
线程之间全局变量都是共享的
3 main
进程必须写 if __name__ == '__main__':
线程由于共享进程的代码,不需要再执行文件中的代码,不需要加上if __name__ == '__main__':
4 效率差别
进程的开启和销毁消耗的时间长
线程的开启和销毁消耗的时间远远小于进程
5 GIL(全局解释器锁)
cpython解释器的GIL 导致python不能有效的利用多核
GIL锁的是线程
6 守护进程和守护线程
守护进程会随着主进程的代码结束而结束,守护进程只关心主进程的执行情况,而不会等待其他子进程的结束
守护线程会随着主线程的结束而结束,而主线程也会等待子线程结束才结束,所以守护线程会等待包括子线程在内的所有线程都结束之后才结束
举一个例子
from threading import Thread import threading from multiprocessing import Process import os import time def func1(): while True: time.sleep(0.5) print('in func1') def func2(): print('start func2') time.sleep(5) print('end func2') if __name__ == '__main__': t=Process(target=func1) t.daemon=True t.start() t2=Process(target=func2) t2.start() print('主') ''' 守护线程的情况 start func2 in func1 in func1 in func1 in func1 in func1 in func1 in func1 in func1 in func1 end func2 #守护进程的情况,守护进程会在主进程代码执行结束后就终止 主 start func2 end func2 '''
7 使用场景
计算密集型 ------------》采用多进程
# from multiprocessing import Process # from threading import Thread # import os,time # def work(): # res=0 # for i in range(10000000): #计算密集型 # res*=i # # # if __name__ == '__main__': # l=[] # start=time.time() # for i in range(8): # p=Process(target=work) #2.0842249393463135 # p=Thread(target=work) # 9.089839935302734 # l.append(p) # p.start() # for p in l: # p.join() # stop=time.time() # # print('run time is %s'%(stop-start))
I/O密集型 ----------------》采用多线程
from multiprocessing import Process from threading import Thread import os,time def work(): time.sleep(2) #I/O型 if __name__ == '__main__': l=[] start=time.time() for i in range(8): # p=Process(target=work) #2.417990207672119 p=Thread(target=work) #2.004342794418335 l.append(p) p.start() for p in l: p.join() stop=time.time() print('run time is %s'%(stop-start))
8 数量限制
进程的数量非常有限: cpu的个数 +1 ,多进程能利用多核,实现高计算
线程的数量限制: cpu的个数 * 5 ,多线程能够实现并发,适合高i/o型