Python中的进程池

进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。

进程池中的函数:

  • apply_async(func[, args[, kwds[, callback]]]) 它是非阻塞,apply(func[, args[, kwds]])是阻塞的
  • close() 关闭pool,使其不在接受新的任务。
  • terminate() 结束工作进程,不在处理未完成的任务。
  • join() 主进程阻塞,等待子进程的退出, join方法要在close或terminate之后使用。

使用进程池

1
2
3
4
5
6
7
8
9
10
11
from multiprocessing import Pool
import time

def function(arg):
time.sleep(1)
print(arg)

pool = Pool(5)
for i in range(16):
# pool.apply(func=function, args=(i,))
pool.apply_async(func=function, args=(i,))

以上代码没有任何返回就立即退出了

因为主进程没有阻塞,没有等待子进程执行完毕就退出了程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from multiprocessing import Pool
import time

def function(arg):
time.sleep(1)
print(arg)

pool = Pool(5)
for i in range(16):
# pool.apply(func=function, args=(i,))
pool.apply_async(func=function, args=(i,))

pool.close()
pool.join() # 调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束

------------
0
3
1
4
2
9
7
6
8
5
10
13
12
14
11
15

join()之前必须等待所有的子进程执行完毕

而等待子进程执行完毕有两种方法,一种是上面的close方法,还有一种是terminate方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from multiprocessing import Pool
import time

def function(arg):
time.sleep(1)
print(arg)

pool = Pool(5)
for i in range(16):
# pool.apply(func=function, args=(i,))
pool.apply_async(func=function, args=(i,))

#pool.close()
time.sleep(1)
pool.terminate()
pool.join()

------------
0
2
1
3
4

close方法与terminate方法的区别是:

  • close:等待所有子进程执行完毕
  • terminate:不管是否正在执行都立即终止

使用进程池并关注结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from multiprocessing import Pool
import time

def function(arg):
time.sleep(1)
return arg

pool = Pool(5)
result = []
for i in range(16):
result.append(pool.apply_async(func=function, args=(i,)))

pool.close()
pool.join()

for r in result:
print("-->", r.get())

------------
--> 0
--> 1
--> 2
--> 3
--> 4
--> 5
--> 6
--> 7
--> 8
--> 9
--> 10
--> 11
--> 12
--> 13
--> 14
--> 15

multiprocessing pool map

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import multiprocessing 

def m1(x):
print(x * x)

if __name__ == '__main__':
pool = multiprocessing.Pool(multiprocessing.cpu_count())
i_list = range(8)
pool.map(m1, i_list)

------------
0
1
4
25
16
9
36
49

参考文档:

http://www.cnblogs.com/kaituorensheng/p/4465768.html

http://www.cnblogs.com/wupeiqi/articles/5040827.html