python多进程multiprocessing模块
使用模块提供了一个Process
类实现多进程:
创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process
实例,用start()
方法启动;
join()
方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步;
使用Process不需要close()直接join()就行。
from multiprocessing import Pool, Process, Queue
import os, time, random
def long_time_task(name, q):
print('Run task %s (%s)...' % (name, os.getpid()))
q.put({"TaskName": name, "pid": os.getpid()})
start = time.time()
time.sleep(random.random()*3)
end = time.time()
print('Task %s runs %0.2f seconds.' % (name, (end - start)))
if __name__=='__main__':
print('Parent process %s.' % os.getpid())
q = Queue()
for i in range(5):
p = Process(target=long_time_task, args=(i, q))
p.start()
p.join()
print('Waiting for all subprocesses done...')
# p.close()
for i in range(q.qsize()):
print(q.get())
print('All subprocesses done.')
运行结果
Parent process 3424.
Run task 0 (6880)...
Task 0 runs 1.21 seconds.
Run task 1 (7344)...
Task 1 runs 1.84 seconds.
Run task 2 (5572)...
Task 2 runs 1.56 seconds.
Run task 3 (6316)...
Task 3 runs 0.67 seconds.
Run task 4 (6196)...
Task 4 runs 2.83 seconds.
Waiting for all subprocesses done...
{'TaskName': 0, 'pid': 6880}
{'TaskName': 1, 'pid': 7344}
{'TaskName': 2, 'pid': 5572}
{'TaskName': 3, 'pid': 6316}
{'TaskName': 4, 'pid': 6196}
All subprocesses done.
Process finished with exit code 0
Pool类
Pool类可以提供指定数量的进程供用户调用,当有新的请求提交到Pool中时,如果池还没有满,就会创建一个新的进程来执行请求。如果池满,请求就会告知先等待,直到池中有进程结束,才会创建新的进程来执行这些请求。
Pool 中提供了如下几个方法:
apply()
apply_async()
map()
map_async()
close()
terminal()
join()
apply和apply_async的区别:
apply方法是阻塞的:
首先主进程开始运行,碰到子进程,操作系统切换到子进程,等待子进程运行结束后,在切换到另外一个子进程,直到所有子进程运行完毕。然后在切换到主进程,运行剩余的部分。
apply_async 是异步非阻塞的:
首先主进程开始运行,碰到子进程后,主进程说:让我先运行个够,等到操作系统进行进程切换的时候,在交给子进程运行。以为我们的程序太短,然而还没等到操作系统进行进程切换,主进程就运行完毕了。
想要子进程执行,就告诉主进程:你等着所有子进程执行完毕后,在运行剩余部分。(p.close(), p.join())