简介
Python多进程主要集中在multiprocessing模块中实现相关功能。如
- 进程的创建(Process)
- Pool的使用(Pool)
- 多个进程之间的数据交换(Queue, Pipes)
- 多个进程之间数据共享(Value, Array, Manager)
- 多个进程之间的同步操作(Lock)
- …
实现样例
在Windows系统实现多进程样例时,
if __name__ == "__main__":
是必要的,确保主模块可以由新的Python解释器安全导入,而不会引起意外的副作用。
Process
使用multiprocessing.Process可以创建一个新的进程,通过start()方法启动进程。
最佳实践是在start()之后执行join()方法,因为在Unix系统当一个进程结束但是没有join,该进程会变成僵尸进程(a zombie)。
但是join()方法在进程使用Queue时则不需要添加,反而可能会因为join方法的添加顺序问题导致死锁。因为一个进程put数据到Queue中会等待数据被消费才会终止,如果存在数据未被消费则进程一直等待。
# Process 构造参数说明
class multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={})
@param group
@param target: run()方法可调用的对象
@param name: 进程名称
@param args: 目标调用对象的参数, 默认无参数调用
@param kwargs: 目标调用的关键字参数字典
# -*- coding:utf-8 -*-
# @author Marvin Yang
# Process示例
from multiprocessing import Process
def multi(x, y):
print "%s multi %s = %s" % (x, y, x*y)
return x * y
def process_demo():
p = Process(target=multi, args=(3, 4))
p.start()
p.join()
def multi_process_demo():
for x in range(0, 5):
for y in range(1, 4):
p = Process(target=multi, args=(x, y))
p.start()
p.join()
if __name__ == "__main__":
# 单个进程
process_demo()
# 多个进程
multi_process_demo()
Pool
进程池可创建多个进程供使用,且提供了多个不同的执行方法。如apply, apply_async, map, map_async等。
# -*- coding:utf-8 -*-
# @author Marvin Yang
# Pool实现样例
from multiprocessing import Process, Pool, Queue
def x2(x):
return x*x
def multi(x, y):
print "%s multi %s = %s" % (x, y, x*y)
return x * y
def pool_demo():
""" map同内置函数map()类似,
将目标调用对象作用于每一个可迭代参数上
意味着如果目标调用对象包含多个参数则不适合用map方法
"""
pool = Pool(processes=4)
print(pool.map(x2, [random.randrange(0, 10), 45, 3, 4, 6]))
def pool_apply_demo():
""" apply同内置apply()类似,
可以有返回值
一个apply使用Pool中的一个进程
"""
pool = Pool(processes=4)
r = pool.apply_async(x2, args=(3, ))
s = pool.apply_async(multi, args=(4, 5))
print(r.get())
print(s.get())
if __name__ == "__main__":
# pool demo
pool_demo()
pool_apply_demo()
Queue
通过Queue实现多个进程之间的数据交换。Pipes同样也可以实现多个进程之间的数据交换,一个头用来输入,一个头用来接收。
# -*- coding:utf-8 -*-
# @author Marvin Yang
from multiprocessing import Process, Pool, Queue
import time
def queue_put_demo(queue):
""" 推送数据到Queue
"""
for i in range(0, 10):
print "input queue: %s" % i
queue.put(["here is a queue demo", "queue", "%s" % i])
#time.sleep(1)
def queue_get_demo(queue):
""" 从Queue中获取数据展示
"""
count = 0
while count < 10 or not queue.empty():
if queue.empty():
time.sleep(2)
else:
obj = queue.get()
for item in obj:
print item, len(item)
count += 1
def queue_demo():
""" 两个进程,一个推送数据到队列,一个从队列中获取数据展示
"""
queue = Queue()
put_p = Process(target=queue_put_demo, args=(queue, ))
get_p = Process(target=queue_get_demo, args=(queue, ))
put_p.start()
get_p.start()
if __name__ == "__main__":
queue_demo()
more
通过上述介绍简单的多进程操作可以满足日常的一些数据处理功能,更多的多进程的细节和功能还需要继续学习。
参考文献
python-2.7.14-docs-html -> module: multiprocessing