python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。Python提供了非常好用的多进程包multiprocessing,只需要定义一个函数,Python会完成其他所有事情。借助这个包,可以轻松完成从单进程到并发执行的转换。multiprocessing支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件。
multiprocessing.Queue()
以Queue为例,在父进程中创建两个子进程,一个往Queue里写数据,一个从Queue里读数据:
multiprcessing.Queue.put() 为 入队操作
multiprcessing.Queue.get() 为 出队操作
队列 线程 和 进程 安全
put(obj[, block[, timeout]])
将obj放入队列。 如果可选参数 block为True(默认值),timeout为None(默认值),则必要时阻止,直到空闲插槽可用。 如果超时是正数,它将阻止最多超时秒数,如果在该时间内没有空闲插槽可用,则会引发Queue.Full异常。 否则(块为False),如果空闲插槽立即可用,则将一个项目放在队列中,否则会引发Queue.Full异常(在这种情况下,忽略超时)。
get([block[, timeout]])
从队列中删除并返回一个项目。 如果可选的args块为True(默认值),超时为None(默认值),则在必要时阻止,直到项目可用。 如果超时为正数,则它将阻塞至多超时秒数,并在该时间内没有可用项目时引发Queue.Empty异常。 否则(block为False),如果一个项目立即可用,返回一个项目,否则会引发Queue.Empty异常(在这种情况下,忽略超时)。
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
|
#- * -coding: utf - 8 - * -
from multiprocessing
import Process, Queue
import os
import time
import random
# 写数据进程执行的代码:
def write(q):
print ( 'Process to write: %s' % os.getpid())
for value in [ 'A' , 'B' , 'C' ]:
print ( 'Put %s to queue...' % value)
q.put(value)
time.sleep(random.random())
# 读数据进程执行的代码:
def read(q):
print ( 'Process to read: %s' % os.getpid())
while True :
value = q.get()
print ( 'Get %s from queue.' % value)
if __name__ = = '__main__' : #父进程创建Queue, 并传给各个子进程:
q = Queue()
pw = Process(target = write, args = (q, ))
pr = Process(target = read, args = (q, )) # 启动子进程pw, 写入:
pw.start() # 启动子进程pr, 读取:
pr.start() # 等待pw结束:
pw.join() # pr进程里是死循环, 无法等待其结束, 只能强行终止:
pr.terminate()
|
输出
1
2
3
4
5
6
7
8
9
10
|
Process to read: 5836
Process to write: 6472
Put A to queue...
Put B to queue...
Get A from queue.
Put C to queue...
Get B from queue.
Get C from queue.
Process finished with exit code 0
|
multiprocessing.Pipe()
Pipe()函数返回一对由管道连接的连接对象,默认情况下是双工(双向)。
Pipe()返回的两个连接对象代表管道的两端。 每个连接对象都有send()和recv()方法(等等)。 请注意,如果两个进程(或线程)尝试同时读取或写入管道的同一端,管道中的数据可能会损坏。 当然,同时使用管道不同端的过程也不会有风险。
返回表示管道末端的一对Connection(conn1,conn2)对象。
如果duplex为True(默认),则管道是双向的。
如果duplex是False,那么管道是单向的:conn1只能用于接收消息,conn2只能用于发送消息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#- * -coding: utf - 8 - * -
from multiprocessing
import Process, Pipe
def f(conn):
conn.send([ 42 , None , 'hello' ])
while True :
print (conn.recv())
if __name__ = = '__main__' :
parent_conn, child_conn = Pipe()
p = Process(target = f, args = (child_conn, ))
p.start()
print parent_conn.recv() # prints "[42, None, 'hello']"
parent_conn.send( '666' )
p.terminate()
|
输出:
1
2
3
4
|
[ 42 , None , 'hello' ]
666
Process finished with exit code 0
|
总结
以上就是本文关于python多进程实现进程间通信实例的全部内容,希望对大家有所帮助。如有不足之处,欢迎留言指出。
原文链接:http://blog.csdn.net/heatdeath/article/details/72844120