Python提供了非常好用的多进程包multiprocessing,只需要定义一个函数,Python会完成其他所有事情。借助这个包,可以轻松完成从单进程到并发执行的转换。multiprocessing支持子进程、通信和共享数据。语法格式如下:
Process([group [, target [, name [, args [, kwargs]]]]]) |
其中target表示调用对象,args表示调用对象的位置参数元组。kwargs表示调用对象的字典。name为别名。group参数未使用,值始终为None。
构造函数简单地构造了一个Process进程,Process的实例方法、Process的实例属性如下表所示。
创建函数并将其作为进程
import multiprocessing
import time,os
#定义进程执行函数
def clock(interval):
for i in range(5):
print('当前时间为{0}:'.format(time.ctime()))
time.sleep(interval)
if __name__=='__main__':
#创建进程
p=multiprocessing.Process(target=clock,args=(1,))
p.name='oscar'
#启动进程
p.start()
#join等待进程p终止,参数为等待多少秒
p.join(3)
#获取进程的ID
print('p.id:',p.pid)
#获取进程的名称
print('p.name:',p.name)
#判断进程是否运行
print('p.is_alive:',p.is_alive())
print('主进程 end')
进程的创建-Process子类
创建进程的方式还可以使用类的方式,可以自定义一个类,继承Process类,每次实例化这个类的时候,就等同于实例化一个进程对象,示例如下:
【示例】继承Process的类,重写run()方法创建进程
#导入模块
from multiprocessing import Process
import time
#定义线程类
class ClockProcess(Process):
def __init__(self,interval):
Process.__init__(self)
self.interval=interval
def run(self):
print('子进程开始执行的时间:{}'.format(time.ctime()))
time.sleep(self.interval)
print('子进程结束的时间:{}'.format(time.ctime()))
if __name__=='__main__':
#创建进程
p=ClockProcess(2)
#启动进程
p.start()
p.join()
print('主进程结束')
进程池
apply_async(func[, args[, kwds[, callback]]]) 它是非阻塞,apply(func[, args[, kwds]])是阻塞的
【示例】进程池的使用(非阻塞)
import multiprocessing
import time
def func(msg):
print("start:", msg)
time.sleep(3)
print("end:",msg)
if __name__ == "__main__":
pool = multiprocessing.Pool(processes = 3)
for i in range(5):
msg = "hello %d" %(i)
#维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去
pool.apply_async(func, (msg, ))
pool.close()#进程池关闭之后不再接收新的请求
#调用join之前,先调用close函数,否则会出错。
# 执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束
pool.join()
【示例】使用进程池(阻塞)
import multiprocessing
import time
def func(msg):
print("start:", msg)
time.sleep(3)
print("end",msg)
if __name__ == "__main__":
pool = multiprocessing.Pool(processes = 3)
for i in range(5):
msg = "hello %d" %(i)
#维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去
pool.apply(func, (msg, ))
pool.close()
#调用join之前,先调用close函数,否则会出错。
# 执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束
pool.join()
进程间通信
全局变量在多个进程中不共享,进程之间的数据是独立的,默认情况下互不影响。
【示例】Queue队列实现进程间通信
from multiprocessing import *
import time
def write(q):
#将列表中的元素写入队列中
for i in ["a","b","c"]:
print('开始写入值%s' % i)
q.put(i)
time.sleep(1)
#读取
def read(q):
print('开始读取')
while True:
if not q.empty():
print('读取到:',q.get())
time.sleep(1)
else:
break
if __name__=='__main__':
#创建队列
q=Queue()
#创建写入进程
pw=Process(target=write,args=(q,))
pr=Process(target=read,args=(q,))
#启动进程
pw.start()
pw.join()
pr.start()
pr.join()