我们在使用Python时,会经常需要使用多进程/多线程的情况,以便提高程序的运行效率,尤其是跟网络进行交互,如使用爬虫时。下面我们将简单看下Python的进程池的创建,map()、apply_async()、apply()的使用。
Pool
可以创建一个进程池,里面是一些工作者进程(Workers),向其提交任务。
创建
class multiprocessing.pool.
Pool
([processes[, initializer[, initargs[, maxtasksperchild[, context]]]]]
- processes:工作进程的数量,如果为None那么processes的值为os.cpu_count()返回的数量,即CPU的个数。
- initializer: 如果initializer是None,那么每一个工作进程在开始的时候会调用initializer(*initargs)。
- maxtasksperchild:工作进程退出之前可以完成的任务数,完成后用一个新的工作进程来替代原进程,来让闲置的资源被释放。maxtasksperchild默认是None,意味着只要Pool存在工作进程就会一直存活。
- context:用在制定工作进程启动时的上下文,一般使用 multiprocessing.Pool() 或者一个context对象的Pool()方法来创建一个池,两种方法都适当的设置了context。
成员函数
- apply_async(func[, args[, kwds[, callback]]]) 它是非阻塞。
- apply(func[, args[, kwds]])是阻塞的。
- close() 关闭pool,使其不在接受新的任务。
- terminate() 关闭pool,结束工作进程,不在处理未完成的任务。
- join() 主进程阻塞,等待子进程的退出, join方法要在close或terminate之后使用。
map
map
(func, iterable[, chunksize])
这种方法将iterable对象分成一些块,作为单独的任务提交给进程池。 这些块的(近似)大小可以通过将chunksize设置为正整数来指定。
#!/usr/bin/env <span class="wp_keywordlink"><a href="http://www.168seo.cn/python" title="python">python</a></span> # -*- coding:utf-8 -*- from <span class="wp_keywordlink_affiliate"><a href="https://www.168seo.cn/tag/multiprocessing" title="View all posts in multiprocessing" target="_blank">multiprocessing</a></span> import Pool import time def test(i): print i time.sleep(1) if __name__ == '__main__': list = [1,2,3,4,5,6,7,8,9] pool = Pool(processes=2) pool.map(test, list) pool.close() pool.join()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from
multiprocessing
import
Pool
import
time
def
test
(
i
)
:
print
i
time
.
sleep
(
1
)
if
__name__
==
'__main__'
:
list
=
[
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
]
pool
=
Pool
(
processes
=
2
)
pool
.
map
(
test
,
list
)
pool
.
close
(
)
pool
.
join
(
)
|
apply
apply
(func[, args[, kwds]])
创建的进程会去执行func函数,并且传递参数args和关键字参数kwds,阻塞型,其实可以看成是单进程,一个执行完毕之后才会执行下一个。
Sample:
#!/usr/bin/env python # -*- coding:utf-8 -*- from multiprocessing import Pool import time def test(i): print i time.sleep(1) if __name__ == '__main__': pool = Pool(processes=10) for i in range(1, 100, 1): # print i pool.apply(test, args=(i,)) print 'test' pool.close() pool.join()</span>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from
multiprocessing
import
Pool
import
time
def
test
(
i
)
:
print
i
time
.
sleep
(
1
)
if
__name__
==
'__main__'
:
pool
=
Pool
(
processes
=
10
)
for
i
in
range
(
1
,
100
,
1
)
:
# print i
pool
.
apply
(
test
,
args
=
(
i
,
)
)
print
'test'
pool
.
close
(
)
pool
.
join
(
)
<
/
span
>
|
apply_async
apply_async
(func[, args[, kwds[, callback[, error_callback]]]])
是上面介绍apply的非阻塞版/异步版。
Sample:
#!/usr/bin/env python # -*- coding:utf-8 -*- from multiprocessing import Pool import time def test(i): print i time.sleep(1) if __name__ == '__main__': pool = Pool(processes=10) for i in range(1, 100, 1): # print i pool.apply_async(test, args=(i,)) print 'test' pool.close() pool.join()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from
multiprocessing
import
Pool
import
time
def
test
(
i
)
:
print
i
time
.
sleep
(
1
)
if
__name__
==
'__main__'
:
pool
=
Pool
(
processes
=
10
)
for
i
in
range
(
1
,
100
,
1
)
:
# print i
pool
.
apply_async
(
test
,
args
=
(
i
,
)
)
print
'test'
pool
.
close
(
)
pool
.
join
(
)
|
apply_async可能也是我们倾向于使用的,大家可以分别运行一下示例,对比看看它们之间的不同。