博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
我的Python成长之路---第八天---Python基础(25)---2016年3月5日(晴)
阅读量:6087 次
发布时间:2019-06-20

本文共 3692 字,大约阅读时间需要 12 分钟。

多进程 multiprocessing模块

multiprocessing模块提供了一个Process类来代表一个进程对象

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
#!/usr/bin/env python3
# coding:utf-8
'''
Created on: 2016年3月5日
 
@author: 张晓宇
 
Email: 61411916@qq.com
 
Version: 1.0
 
Description: 多进程演示程序
 
Help:
'''
from
multiprocessing
import
Process
import
os
 
 
def
run_proc(name):
    
# 子进程要执行的函数
    
print
(
'Run child process %s (%s)...'
%
(name, os.getpid()))
# os.getpid()表示获得当前进程的pid
 
if
__name__
=
=
'__main__'
:
    
print
(
'Parent process %s.'
%
os.getpid())
# 打印父进程的pid
    
p
=
Process(target
=
run_proc, args
=
(
'test'
,))
# 创建进程对象,参数结构和多线程一样
    
print
(
'Child process will start.'
)
    
p.start()
# 启动子进程
    
p.join()
# 阻塞等待子进程执行完毕
    
print
(
'Child process end.'
)

进程间通信

Queue

不同进程间内存是不共享,所以多进程不能像多线程一样通过全局变量(当然全局变量也是不提倡的),所以只能通过队列,多进程模块也自带一个队列Queue,使用方法和threading里的queue差不多

Pipe

管道,可以理解为两个进程之间的一个桥梁

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
#!/usr/bin/env python3
# coding:utf-8
'''
Created on: 2016年3月5日
 
@author: 张晓宇
 
Email: 61411916@qq.com
 
Version: 1.0
 
Description: 管道演示程序
 
Help:
'''
from
multiprocessing
import
Process, Pipe
 
def
f(conn):
    
conn.send([
42
,
None
,
'hello'
])
# 网管道里传递数据
    
conn.close()
 
if
__name__
=
=
'__main__'
:
    
parent_conn, child_conn
=
Pipe()
# 一个是父进程的管道对象,一个是子进程的对象,自己成往里面send,父进程对象recv,有点像socket
    
p
=
Process(target
=
f, args
=
(child_conn,))
# 把管道对象作为参数传递给子进程
    
p.start()
    
print
(parent_conn.recv())  
# 接收管道里的数据并打印出来
    
p.join()

执行结果

1
[
42
,
None
,
'hello'
]

有人会说既然可以往子进程要执行的而函数传递参数,直接通过这个参数取子进程传递过来的数据就好了,比如可以用列表等可变数据类型(字符串和数值型等不可变类型的数据,想都不要想,统一进程都做不到)为啥还用管道或队列

 

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
#!/usr/bin/env python3
# coding:utf-8
'''
Created on: 2016年3月5日
 
@author: 张晓宇
 
Email: 61411916@qq.com
 
Version: 1.0
 
Description: 管道演示程序
 
Help:
'''
from
multiprocessing
import
Process, Pipe
 
def
f(conn, strinfo):
    
conn.send([
42
,
None
,
'hello'
])
# 网管道里传递数据
    
conn.close()
# 关闭管道
    
strinfo.append(
'child'
)
 
if
__name__
=
=
'__main__'
:
    
parent_conn, child_conn
=
Pipe()
# 一个是父进程的管道对象,一个是子进程的对象,自己成往里面send,父进程对象recv,有点像socket
    
strinfo
=
[
'parent'
]
    
p
=
Process(target
=
f, args
=
(child_conn, strinfo))
# 把管道对象作为参数传递给子进程
    
p.start()
    
print
(parent_conn.recv())  
# 接收管道里的数据并打印出来
    
print
(strinfo)
    
p.join()

执行结果

1
2
[
42
,
None
,
'hello'
]
['parent']

从执行结果中可以看出来,strinfo的值并没有变化,那是因为,进程启动的时候重新划分了内存空间,等于将strinfo在子进程中copy了一份,已经和父进程中的strinfo没有半毛钱关系了所以要有管道队列等

进程池

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

Pool模块有两种常用的启动进程的方法

apply和apply_assync,从字面上理解是apply_assync是异步的,其实就是apply_assync支持把一个函数作为参数传递进去,当进程函数执行完的时候可以通过return一个值,这个值,会自动作为参数传递个传递进来的函数,并执行该函数,我们称之为回调(callback)

 

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
36
37
38
39
40
41
42
43
44
45
#!/usr/bin/env python
# coding:utf-8
'''
Created on: 2016年3月5日
 
@author: 张晓宇
 
Email: 61411916@qq.com
 
Version: 1.0
 
Description: 进程池演示程序
 
Help:
'''
from 
multiprocessing
import
Pool, freeze_support
import
time
 
def
Foo(i):
    
'''
    
子进程执行的函数
    
:param i:
    
:return:
    
'''
    
time.sleep(
2
)
    
return
i
+
100
 
def
Bar(arg):
    
'''
    
子进程回调函数
    
:param arg:
    
:return:
    
'''
    
print
(
'-->exec done:'
,arg)
 
if
__name__
=
=
'__main__'
:
# 这个在windows环境中绝对不能省略否则会报错
    
freeze_support()
    
pool
=
Pool(
5
)
# 创建进程池对象
 
    
for
i
in
range
(
10
):
        
pool.apply_async(func
=
Foo, args
=
(i,), callback
=
Bar)
        
# pool.apply(func=Foo, args=(i,))
    
print
(
'end'
)
    
pool.close()
    
pool.join()
#进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。

执行结果

1
2
3
4
5
6
7
8
9
10
11
end
-
-
>
exec
done:
100
-
-
>
exec
done:
101
-
-
>
exec
done:
102
-
-
>
exec
done:
103
-
-
>
exec
done:
104
-
-
>
exec
done:
105
-
-
>
exec
done:
106
-
-
>
exec
done:
107
-
-
>
exec
done:
108
-
-
>
exec
done:
109

 

转载于:https://www.cnblogs.com/zhangxiaxuan/p/5502423.html

你可能感兴趣的文章
React Native 极光推送填坑(ios)
查看>>
Terratest:一个用于自动化基础设施测试的开源Go库
查看>>
修改Windows远程终端默认端口,让服务器更安全
查看>>
扩展器必须,SAS 2.0未必(SAS挺进中端存储系统之三)
查看>>
Eclipse遇到Initializing Java Tooling解决办法
查看>>
while((ch = getchar()) != '\n')
查看>>
好程序员web前端分享JS检查浏览器类型和版本
查看>>
Oracle DG 逻辑Standby数据同步性能优化
查看>>
exchange 2010 队列删除
查看>>
「翻译」逐步替换Sass
查看>>
H5实现全屏与F11全屏
查看>>
处理excel表的列
查看>>
C#数据采集类
查看>>
quicksort
查看>>
【BZOJ2019】nim
查看>>
LINUX内核调试过程
查看>>
【HDOJ】3553 Just a String
查看>>
Java 集合深入理解(7):ArrayList
查看>>
2019年春季学期第四周作业
查看>>
linux环境配置
查看>>