进程间的消息传输:管道、消息队列、共享内存

  • 进程间通信(IPC)
	原因:进程空间相对独立,资源无法相互获取,此时在不同进程间通信需要专门方法。

	 进程间通信方法:管道 消息队列 共享内存 信号 信号量套接字
  • 管道通信 Pipe
通信原理:在内存中开辟管道空间,生成管道操作对象,多个进程使用“同一个”管道对象进行操作即可实现通信

multiprocessing--》 Pipe

fd1,fd2 = Pipe(duplex = True)
	功能:创建管道
	参数:默认表示双向管道
		 设置False则为单向管道
	返回值:表示管道的两端
		 如果是双向管道 都可以读写
		 如果是单向管道 则fd1只读 fd2只写

fd.recv()
	功能:从管道读取信息
	返回值:读取到的内容
* 如果管道为空则阻塞

fd.send(data)
	功能:向管道写入内容
	参数:要写入的内容
 * 可以发送python数据类型,不用是byte格式
  • 管道通信简单实现
#使用管道进行进程间的通信
from multiprocessing import Process,Pipe
import os,time

#创建管道对象,若是单向管道,fd2只写,fd1只读
fd1, fd2 = Pipe(False) 

def fun(name):
	time.sleep(3)
	#向管道中写入内容
	fd2.send('hello ' + str(name))

jobs = []
for i in range(5):
	p = Process(target = fun,args = (i,))
	jobs.append(p)
	p.start()

for i in range(5):
	#父进程读取管道
	data = fd1.recv()
	print(data)

for i in jobs:
	i.join()
  • 消息队列
通信原理:
	在内存中简历队列数据结构模型,多个进程都可以通过队列存入内容,取出内容的顺序和存入顺序保持一致

创建队列
	q = Queue(maxsize = 0)
	功能:创建消息队列
	参数:表示最多存放多少消息。默认表示根据内存分配存储
	返回值:队列对象
	
	q.put(data,[block,timeout])
	功能:向队列存储消息
	参数:data 要存的内容
		 block 默认队列满时会阻塞,设置为False则非阻塞
		 timeout 超时时间

	q.get([block,timeout])
	功能:获取队列消息
	参数:block 默认队列空时会阻塞,设置为Faslse则非阻塞
		 timeout超时时间
	返回值: 返回取出的内容

	q.full() 判断队列是否为满
	q.empty() 判断队列是否为空
	q.qsize() 判断队列中的消息数量
	q.close() 关闭队列
  • 消息队列简单演示
#创建消息队列,实现进程间通信
from multiprocessing import Queue
from time import sleep

#创建队列
q = Queue(3)

q.put(1)
print(q.qsize())
print(q.full())

q.put(2)
print(q.qsize())
print(q.full())

q.put(3)
print(q.qsize())
print(q.full())

#q.put(4,True,3) 如果设置非阻塞,满后再加会报错
#若设置True,并添加超时时间,超过时间后仍然会报错

for _ in range(q.qsize()): print(q.get()) # 1 2 3
  • 消息队列通信简单实现
#创建消息队列,实现进程间通信
from multiprocessing import Process,Queue
import time

#创建消息队列
q = Queue()

def fun1():
	time.sleep(1)
	q.put({'a':1,'b':2})

def fun2():
	time.sleep(2)
	print('收到消息:',q.get())

p1 = Process(target = fun1)
p2 = Process(target = fun2)
p1.start()
p2.start()
p1.join()
p2.join()
  • 共享内存
	通信原理:在内存中开辟一块空间,对多个进程可见,进程可以写入输入,但是每次写入的内容会覆盖之前的内容。

创建共享内存
	obj = Value(ctype,obj)
		功能:开辟共享内存空间
		参数: ctype 要存储的数据类型
			   obj 共享内存的初始化数据
		返回: 共享内存对象
	
	obj.value 即为共享内存值,对其修改即修改共享内存
	
	obj.Array(ctype,obj)
	功能:开辟共享内存空间
	参数: ctype 要存储的数据类型
		   obj 初始化存入的内容 比如列表,字符串
		   如果是整数则表示开辟空间的个数 
	返回值:返回共享内存对象
		  * 可以通过返回值遍历每个元素的值
		    [1,2,3] --> obj[1] == 2
		  * 如果存入的是字符串
		    obj.value 表示字符串的首地址
  • 共享内存Value对象的通信实现
from multiprocessing import Process,Value
import time
import random

#创建共享内存
money = Value('i',2000)

#操作共享内存存钱
def deposite():
	for i in range(100):
		time.sleep(0.05)
		#对value属性操作共享内存数据
		money.value += random.randint(1,200)

#操作共享内存取钱
def withdraw():
	for i in range(100):
		time.sleep(0.04)
		#对value属性操作共享内存数据
		money.value -= random.randint(1,180)

d = Process(target = deposite)
w = Process(target = withdraw)

d.start()
w.start()

d.join()
w.join()

print('余额为',money.value)
  • 共享内存Array对象的通信实现
#创建共享内存存入列表
from multiprocessing import Process,Array
import time

#创建共享内存,初始放入列表
#shm = Array('i',[1,2,3,4,5])
#创建共享内存,开辟5个整形空间
shm = Array('i',5)

def fun():
	for i in shm:
		print(i)
	shm[3] = 199

p = Process(target = fun)
p.start()
p.join()

for i in shm:
	print(i)

在这里插入图片描述
表中的Type code为Value方法的Ctype参数类型

  • 三种通信方式对比
			管道		消息队列		共享内存
开辟空间		内存		  内存		  内存		
读写方式		两端读写		先进先出		覆盖之前内容
效率		一般		  一般		  较高

 * 管道多用于父子进程
 * 消息队列广泛灵活
 * 共享内存需要注意进行互斥操作
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值