首先来说说他两个的区别,进程是资源分配的最小单位,线程则是CPU调度的最小单位,多进程不能共享全局变量,当使用全局变量的时候势必会造成,race condition,而多线程则可以共享全局变量,对于大量需要CPU工作的时候,进程就显得大有优势,因为多线程需要CPU来不停切线程换大量时间都消耗在,切换线程上,而对于IO操作上(比如文件存储,网络爬虫),多线程就有巨大优势。
下面来一些简单的小例子:
进程:
from multiprocessing import Process
def run(num):
print('this is process')
for i in range(5):
print(num,i)
if __name__ =='__main__':
for i in range(5):
p = Process(target=run,args=(i,))#创建多个进程
p.start()#启动
p.join()
线程:
import threading
def run(num):
print('hello everyone')
for i in range(5):
print('%s -- %d' % (threading.current_thread().name, i))#注意这里的'threading.current_thread().name'这个是获取当前正在运行的线程名字
if __name__ == '__main__':
for i in range(5):
s = threading.Thread(target=run, args=(i,))#创建多个线程
s.start()#启动线程
以上是最简单的多进程和多线程
当多个线程同时处理同样一个逻辑的时候,就会造成数据混乱如下:
import threading
num = 0#定义全局的变量
def func1(n):
global num
for i in range(100000):
num = num - n
num = num + n
if __name__ =='__main__':
s =threading.Thread(target=func1,args=(6,))
s1 =threading.Thread(target=func1,args=(9,))
s.start()
s1.start()
s.join()
s1.join()
print(num)
打印结果为 -6,
正常情况下,应该为0为什么会变成-6呢?因为多线程是共享全局变量的,造成了多个线程运行时产生了数据混乱,为了解决这个问题,我们可以引入,线程锁的概念:
线程锁的应用:
import threading
lock = threading.Lock()#这里我们创建一个锁的实例
num =0
def func1(n):
global num
for i in range(100000):
lock.acquire()#这里上锁
try:#
num = num-n
num = num+n
finally:
lock.release()#释放锁
if __name__ =='__main__':
s =threading.Thread(target=func1,args=(6,))
s1 =threading.Thread(target=func1,args=(9,))
s.start()
s1.start()
s.join()
s1.join()
print(num)
打印结果为 0
锁是怎么工作的呢?其实当一个线程遇到lock.acquire()的时候会上锁,其他大的线程就会在此挂起,等线程遇到lock.release()就会把锁释放,被挂起的线程才会进入逻辑运算,避免了多个线程同时运算造成的结果混乱。为什么加 try---finally 呢?因为在大量计算中可能会出现不可预期的错误,从而导致线程锁一直被锁死,导致整个程序报废。
总结:对于计算密集型多进程优势,对于io密集型多线程有优势。注意线程锁的应用。