一、multiprocessing 简介
python中的多线程无法利用多核优势,如果想要充分使用多核CPU的资源,就要采用多进程的方式。multiprocessing模块,支持子进程、通信和共享数据、执行不同形式的同步,提供Process、Queue、Pipe、Lock等组件。
二、使用实践
大多数情况都是要处理较多数据才会使用多进程。
所以引入队列
import time
from multiprocessing import Process,Queue,Lock,process
def run(q):
while True:
if q.empty():
break
else:
num=q.get()
time.sleep(0.5)
print (process.current_process().name)
print("输出了"+str(num))
def listToQueue(dataList):
q = Queue(len(dataList))
for data in dataList:
q.put(data)
return q
if __name__=="__main__":
dataList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
q = listToQueue(dataList)
for i in range(10):
#target指向要执行的函数名,args传递参数,需要为tuple,数据存到队列中,将队列传到函数中,循环消耗掉
p=Process(target=run, args=(q,))
p.start()
输出结果:
Process-1
输出了1
Process-6
输出了2
Process-4Process-3Process-2
输出了3
输出了4输出了5
Process-5
输出了6
Process-8Process-9
输出了7输出了8
Process-7
输出了9
Process-10
输出了0
可以看到的是有结果输出的时候写到了一起。说明进程产生了竞争。
此时就需要加锁处理。但是加锁后效率会降低,根据自己项目需求而定
import time
from multiprocessing import Process,Queue,Lock,process
def run(q,lock):
while True:
if q.empty():
break
else:
lock.acquire()
num=q.get()
time.sleep(1)
print (process.current_process().name)
print("输出了"+str(num))
lock.release()
def listToQueue(dataList):
q = Queue(len(dataList))
for data in dataList:
q.put(data)
return q
if __name__=="__main__":
lock=Lock()
dataList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
q = listToQueue(dataList)
for i in range(10):
#加入lock
p=Process(target=run, args=(q,lock))
p.start()
输出结果
Process-1
输出了1
Process-2
输出了2
Process-5
输出了3
Process-3
输出了4
Process-4
输出了5
Process-9
输出了6
Process-6
输出了7
Process-10
输出了8
Process-7
输出了9
Process-8
输出了0
采用继承的方式
import time
from multiprocessing import Queue,Process
def listToQueue(dataList):
q = Queue(len(dataList))
for data in dataList:
q.put(data)
return q
class Run(Process):
def __init__(self,q):
super(Run,self).__init__()
self.q=q
def run(self):
while True:
if self.q.empty():
break
else:
num=self.q.get()
time.sleep(5)
print(num)
print (self.name)
#time.sleep(1)
if __name__=="__main__":
dataList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
q = listToQueue(dataList)
for i in range(10):
myrun.start()