python 多进程 (multiprocessing)
开启一个进程的方法
- 导入multiprocessing,用multiprocessing.Process(target=函数,args=(参数,))
import multiprocessing
import time
v = []
def fun1(arg):
p = multiprocessing.current_process()
print(p.name,p.ident)#获取当前进程的名称,id(或者p.pid)
v.append(arg)
print(v)
def run():
for i in range(4):
process = multiprocessing.Process(target=fun1,args=(i,))#开启一个进程
process.daemon = False #等待子进程结束,默认True,不等待
process.start()#开始执行
process.join()#等待上一个进程结束后执行下一个,或者等带指定秒后执行下一个process.join(N)
if __name__ == '__main__': #windows下执行方式,必须在if __name__ == '__main__':下
run()
- 使用面向对象的方式(类继承)创建进程,继承multiprocessing.Process类,并实现run方法即可
import multiprocessing
import time
class MyProcessing(multiprocessing.Process): #需要继承multiprocessing.Process类
def run(self):#需要实现run方法,和线程相似(threading.Thread)
print('当前进程:%s' % multiprocessing.current_process())
def run():
for i in range(4):
process = MyProcessing()#开启一个进程
process.daemon = False #等待子进程结束,默认True,不等待
process.start()#开始执行
process.join()#等待上一个进程结束后执行下一个,或者等带指定秒后执行下一个process.join(N)
if __name__ == '__main__': #windows下执行方式,必须在if __name__ == '__main__':下
run()
进程的数据共享
- 和线程不同,各进程之间的数据是不共享的因此线程之间为了避免数据混乱需要加锁,而进程之间数据共享也需要其他操作实现.
- 使用 multiprocessing.Manager(),数据管理器,支持类型有list,dict
import multiprocessing
import time
def fun1(arg,dic):
dic[arg] = 1
print(dic)
def run(arg):
for i in range(4):
process = multiprocessing.Process(target=fun1,args=(i,dic))#开启一个进程
process.start()#开始执行
process.join()
if __name__ == '__main__': #windows下执行方式,必须在if __name__ == '__main__':下
m = multiprocessing.Manager()
dic = m.dict()
run(dic)
- 使用 multiprocessing.Queue()队列
import multiprocessing
import time
def fun1(arg,q):
q.put(arg)
print(q.qsize())#获取队列长度
def run(arg):
for i in range(4):
process = multiprocessing.Process(target=fun1,args=(i,q))#开启一个进程
process.start()#开始执行
process.join()
if __name__ == '__main__': #windows下执行方式,必须在if __name__ == '__main__':下
q = multiprocessing.Queue()
q.qsize()
run(q)
进程锁(用到同一个数据时需要加锁)
- Lock(), 锁定一个代码块,进行该代码块时,别的进程无法对其进行操作
import multiprocessing
import time
lock = multiprocessing.Lock() #创建锁
def fun1(arg):
print(multiprocessing.current_process().name)
lock.acquire()
time.sleep(1)
print(arg)#获取队列长度
lock.release()
def run():
for i in range(4):
process = multiprocessing.Process(target=fun1,args=(i,))#开启一个进程
process.start()#开始执行
process.join()
if __name__ == '__main__': #windows下执行方式,必须在if __name__ == '__main__':下
run()
- Rlock, 和Lock(),用法相同,但是支持加锁多次,和解锁多次,一般加锁常用RLock
import multiprocessing
import time
lock = multiprocessing.RLock()
def fun1(arg):
print(multiprocessing.current_process().name)
lock.acquire()
time.sleep(1)
print(arg)#获取队列长度
lock.release()
def run():
for i in range(4):
process = multiprocessing.Process(target=fun1,args=(i,))#开启一个进程
process.start()#开始执行
process.join()
if __name__ == '__main__': #windows下执行方式,必须在if __name__ == '__main__':下
run()
- BoundedSemaphore(N) , 可设置通过的个数N
import multiprocessing
import time
lock = multiprocessing.BoundedSemaphore(1)#设置通过的个数
def fun1(arg):
print(multiprocessing.current_process().name)
lock.acquire()
time.sleep(1)
print(arg)#获取队列长度
lock.release()
def run():
for i in range(10):
process = multiprocessing.Process(target=fun1,args=(i,))#开启一个进程
process.start()#开始执行
if __name__ == '__main__': #windows下执行方式,必须在if __name__ == '__main__':下
run()
- Event(),一次释放所有进程
import multiprocessing
import time
lock = multiprocessing.Event()
def fun1(arg):
print(multiprocessing.current_process().name)
lock.wait()#加锁,锁住之下代码
time.sleep(1)
print(arg)#获取队列长度
def run():
for i in range(4):
process = multiprocessing.Process(target=fun1,args=(i,))#开启一个进程
process.start()#开始执行
if __name__ == '__main__': #windows下执行方式,必须在if __name__ == '__main__':下
run()
lock.set()#释放所有
进程池(重点)
1.和线程池一样,从 concurrent.futures 导入 ProcessPoolExecutor
from concurrent.futures import ProcessPoolExecutor
import multiprocessing
import time
pool = ProcessPoolExecutor(4)#进程池,几核的cpu就设置几个进程
def func(arg):
time.sleep(1)
print(multiprocessing.current_process().name,arg)
if __name__ == '__main__':#windows,只能在其下面才能运行
for i in range(20):
pool.submit(func,i)