在python中大部分情况需要使用多进程,那么这个包就叫做 multiprocessing。
通过它可以很检点的完成单进程到并发执行的转换。
multiprocessing支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件。
Process
在multiprocessing中,每一个进程都用一个Process类来表示
Process([group [, target [, name [, args [, kwargs]]]]]) |
- target表示调用对象,你可以传入方法的名字
- args表示被调用对象的位置参数元组,比如target是函数a,他有两个参数m,n,那么args就传入(m, n)即可
- kwargs表示调用对象的字典
- name是别名,相当于给这个进程取一个名字
- group分组,实际上不使用
简单展示:
import multiprocessing
def process(num):
print('Process:', num)
if __name__ == '__main__':
strs = 'abcdefgjinml'
for i in strs:
# target传入函数名,args是函数的参数,是元组的形式
p = multiprocessing.Process(target=process, args=(i,))
# 启动
p.start()
cpu_count() 获取当前机器的 CPU 核心数量。
multiprocessing.cpu_count()
active_children() 得到目前所有的运行的进程。
for p in multiprocessing.active_children():
# 进程名字和进程id
print(p.name,p.pid)
自定义类:
继承了 Process 这个类,然后实现了run方法
我们可以把一些方法独立的写在每个类里封装好,等用的时候直接初始化一个类运行即可。
from multiprocessing import Process
class MyProces(Process):
def __init__(self,strs):
# 初始化,继承父类
Process.__init__(self)
self.strs = strs
def run(self):
print( self.strs,self.pid,self.name)
if __name__ == '__main__':
strs = 'abcdefgjicklmn'
for i in strs:
p = MyProces(i)
p.start()
print('over')
deamon属性 : 如果设置为True,当父进程结束后,子进程会自动被终止。这样关闭这个主程序运行时,就无需额外担心子进程有没有被关闭。
if __name__ == '__main__':
strs = 'abcdefgjicklmn'
for i in strs:
p = MyProces(i)
p.daemon =True
p.start()
print('over')
运行后会发现只打印出几条数据,是因为主进程以及执行完,子进程还没运行完将被直接结束了,可以通过join()来解决。
join()方法:阻塞、等待所有子进程都执行完了然后再结束主进程。
每个子进程都调用了join()方法,这样父进程(主进程)就会等待子进程执行完毕。
if __name__ == '__main__':
strs = 'abcdefgjicklmn'
for i in strs:
p = MyProces(i)
p.start()
p.join()
print('over')
这样也可以发现输出的时候是按顺序输出,不会那么乱
a 6996 MyProces-1
b 7312 MyProces-2
c 8156 MyProces-3
d 7100 MyProces-4
。。。
n 8112 MyProces-14
over
Lock锁:
有时候因为并行的原因导致俩个进程同时进行了输出,而第一个换行还没来得及做。导致的乱行显示,可以通过给输出加锁来解决
import time
from multiprocessing import Process,Lock
class MyProces(Process):
def __init__(self,strs,lock):
# 初始化,继承父类
Process.__init__(self)
self.strs = strs
self.lock = lock
def run(self):
time.sleep(1)
self.lock.acquire() # 加锁
print( self.strs,self.pid,self.name)
self.lock.release() # 解锁
if __name__ == '__main__':
lock = Lock()
strs = 'abcdefgjicklmn'
for i in strs:
p = MyProces(i,lock)
p.start()
print('over')
创建一个锁,在需要加的地方acquire(),释放的地方release()
进程池Pool
Pool类可以提供指定数量的进程供用户调用,当有新的请求提交到Pool中时,如果池还没有满,就会创建一个新的进程来执行请求。如果池满,请求就会告知先等待,直到池中有进程结束,才会创建新的进程来执行这些请求。