IPC(Inter-Process Communication):进程间通信
起源:
在项目中单进程无法满足需求时,可能 多进程是一种解决方案, 但是进程间在 需要相互沟通交流协作的时候 就需要进程间能够相互通信;
进程间通信的方式:
- 共享内存: 多个进程间 共享一块内存区域,进程间向此内存区域 读写数据,从而完成数据共享,进而完成进程间通信; 这块内存区域支持的数据类型如下(multiprocessing.Manager的):
list
,dict
,Namespace
,Lock
,RLock
,Semaphore
,BoundedSemaphore
,Condition
,Event
,Barrier
,Queue
,Value
和Array
. - 消息传递: 通过 队列(queue,大于等于2个进程可以使用,可以一个生产者多个消费者)或者管道(pipe,只能2个进程相互通信,只能一个生产者,一个消费者) 实现 生产者-消费者模式 下的 进程间通信;
各种实现代码示例:
1.共享内存 使用 multiprocessing.Manager中的list,dict实现
# -*- coding: utf-8 -*-
"""
(C) rgc
All rights reserved
create time '2021/1/28 10:38'
Usage:
"""
from multiprocessing import Process, Manager
def insert(d, l):
"""
共享数据新增 进程
:param d:
:param l:
:return:
"""
for item in range(1, 10):
print('新增 list,dict', item)
d[item] = item
l.append(item)
def pop(d: dict, l: list):
"""
共享数据删除 进程
:param d:
:param l:
:return:
"""
while True:
if len(d.keys()):
for k in list(d.keys()):
print('删除_dict的', k, d[k])
del d[k]
if len(l):
rs = l.pop()
print('删除list', rs)
if __name__ == '__main__':
with Manager() as manager:
d = manager.dict()
l = manager.list()
p = Process(target=insert, args=(d, l))
p1 = Process(target=pop, args=(d, l))
p.start()
p1.start()
p.join()
p1.join()
# p1.terminate()
2.消息传递 使用pipe(管道) 实现
# -*- coding: utf-8 -*-
"""
(C) rgc
All rights reserved
create time '2021/1/28 10:38'
Usage:
"""
from multiprocessing import Process, Pipe
def pipe_frontend(p: Pipe, l: list):
"""
餐厅前台通过管道发送/接收数据
前台负责 发送制作任务,接收 制作完成通知
:param l:
:return:
"""
for item in l:
print(f'开始发送制作:{item} 任务')
# 发送
p.send(item)
while True:
# 接收
item = p.recv()
print(item, '可以端给食客享用')
def pipe_backend(p: Pipe):
"""
餐厅后台通过管道接收,进行处理后,发送数据
后台负责 接收制作任务,并在制作完成后,发送制作完成通知
:param p:
:return:
"""
while True:
# 接收
item = p.recv()
print(f'开始接收:{item}任务,并进行制作')
_send = f'制作{item}完成'
# 发送
p.send(_send)
print(f'{_send},推送此消息到管道')
if __name__ == '__main__':
# 参数 duplex 值为True表示 全双工模式(两头均可发送接收),False表示 单工模式(p[1]只能发送,p[0]只能接收)
p = Pipe(True)
p_product = Process(target=pipe_frontend, args=(p[0], ['饺子']))
p_consumer = Process(target=pipe_backend, args=(p[1],))
p_product.start()
p_consumer.start()
p_product.join()
p_consumer.join()
# p_consumer.terminate()
3.消息传递 使用queue(队列) 实现
# -*- coding: utf-8 -*-
"""
(C) rgc
All rights reserved
create time '2021/1/28 10:38'
Usage:
"""
from multiprocessing import Process, Queue
def queue_insert(q: Queue, l: list):
"""
队列插入数据
:param l:
:return:
"""
for item in l:
print(f'开始制作:{item}')
q.put(item)
def queue_pop(q: Queue):
"""
队列弹出数据,并进行处理
:param q:
:return:
"""
while True:
item = q.get(True)
print(f'开始吃:{item}')
if __name__ == '__main__':
q = Queue()
p_product = Process(target=queue_insert, args=(q, ['饺子', '稀饭', '面皮']))
p_product1 = Process(target=queue_insert, args=(q, ['苹果', '车厘子', '香蕉']))
p_consumer = Process(target=queue_pop, args=(q,))
p_consumer1 = Process(target=queue_pop, args=(q,))
p_product.start()
p_consumer.start()
p_product1.start()
p_consumer1.start()
p_product.join()
p_product1.join()
p_consumer.join()
p_consumer1.join()
# p_consumer.terminate()
# p_consumer1.terminate()
4. 其他的还有 SimpleQueue , JoinableQueue
相关链接: http://c.biancheng.net/view/1208.html