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())

python多进程multiprocessing模块

注意:close必须在join前调用。

python官方建议:废弃apply,使用apply_async。