进程间通信之消息队列

进程间通信之消息队列

1.按照先进先出的原则来存取消息,先放入的消息先被取出

2. 队列中没有消息则为空队列,这是无法执行取消息的操作。队列中消息个数达到上限则为满队列此时无法存入消息

3. 不同进程间,通过向队列存入和获取消息来达到通信的目的

from  multiprocessing  import  Queue

q = Queue(maxsize) 
功能 :创建消息队列对象
maxsize :  设置消息队列大小,表示最多存多少个消息

q.put(obj,block = True,timeout = None)
功能:向队列中存入消息
obj :要存入的对象
block:是否是阻塞模式,默认是True 如果设置为False为非阻塞

timeout: 当block = True时为阻塞时间

q.get()
功能:从队列中取出一个消息
block:默认为True 表示阻塞,设置为false表示为非阻塞则如果队列为空立即返回empty异常
timeout: block= True 时 表示阻塞等待时间,超时则返回异常



q.full()
判断队列是否为满,如果满则返回True否则返回false

q.empty()
判断队列是否为空,如果空则返回True否则返回false

q.qsize() 
查看当前队列中消息的个数

练习:
父进程 : 从终端获取输入内容,放入到消息队列

子进程 : 从消息队列中得到内容,然后打印出来

共享内存:

特点 :1. 效率高的进程间通信方式
       2. 安全性上有风险,因为内容的存放是会覆盖原有内容的,所以在使用时很可能已经被篡改
			 3. 基于2的原因,在使用时经常需要考虑加锁问题

from multiprocessing import Value,Array

1.两种方法使用上基本相同,value在共享内存存放一个数值,array可以存放多个数值,但是类型必须相同

2.任意的进程对共享内存中的数据进行修改后,即其他进程也会获得修改后的数据

3. 两个方法第一个参数相同,都是ctypes,详见表。第二个参数 value为一个相应类型的数值,array可以是数值(表示开辟一个包含多少数据的内存空间填充0),也可以是一个迭代对象(会给距迭代内容开辟空间并且将内容进行填充)

           管道         消息队列     共享内存

开辟空间   内存         内存         内存

读写方式   可双向 单向  先进先出     操作内存
           消息流       个数         数值数组 
					 send/recv    put/get      直接修改

效率       一般         一般          快

是否需要   不需要       不需要       需要
互斥


信号 :

是一种异步的进程间通信方式

信号 有其名称,含义,和默认行为 

发送信号
import os

os.kill(pid,sig)
功能:向一个进程发送一个信号
pid : 向哪个进程发送,该进程的PID号
sig : 发送什么信号  使用 signal.signum

signal.alarm(sec)
功能:向自身发送一个信号
sec: 在sec秒后信号会被发送

* 一个进程中只能挂起一个时钟信号

处理信号

signal.pause()
功能:挂起等待一个信号

signal.signal(signum,handler)
功能:处理一个信号
参数: signum : 要处理的信号
       handler: 对信号的处理方法
			 处理方法:忽略该信号     SIG_IGN
                 使用默认方法执行 SIG_DFL
								 使用指定方法执行 function 

异步处理 : 在某一时刻使用signal扑捉信号,会告知内核帮进程监控,而不是阻塞等待。在进程的生命周期内,只要有该信号发送进来就会处理。

僵尸进程处理 
父进程在子进程执行结束前加入:
signal.signal(signal.SIGCHLD,signal.SIG_IGN)


同步和互斥 

临界资源 : 对多个进程或线程可见,容易产生争夺的资源(如共享内存)称之为临界资源

临界区 : 对临界资源进行操作的代码段,称之为临界区

同步 : 同步是一种制约关系,为完成某种任务而建立两个或多个进程,进程间协调而有次序的等待,传递信息,完成工作。这种制约源于进程间的合作

互斥 :互斥是一种间接的制约,当一个进程进入临界区进行加锁,其他进程此时无法操作临界资源,只有当该进程结束对临界资源的使用后,进行解锁,其他进程才可以使用。这种技术往往是通过阻塞完成的

同步互斥方法

Event 

e = Event()   创建事件对象

e.is_set()   判断事件是否被设置

e.set()   对事件对象进行设置

e.wait(2)   阻塞等待时间被设置 (参数表示超时时间)

Lock 
from multiprocessing import Lock
lock = Lock()

lock.acquire()  上锁 
lock.release()  解锁

with lock: 上锁

作业 : 
司机和售票员的故事 

1. 创建父子进程分别表示司机和售票员
2. 当售票员扑捉 SIGINT 信号时 ,发送SIGUSR1给司机,司机打印(‘发车了’)
   
	 当售票员捕捉到 SIGQUIT 信号时,发送SIGUSR2给司机,司机打印('停车')
   
	 司机捕捉到 SIGTSTP, 发送 SIGUSR1给售票员,
	 售票员打印(‘到站了 请下车’)
3.到站后司机等待售票员先下车,然后自己exit

温馨提示 : 当通过键盘发送信号时,会发送给终端的所有进程

猜你喜欢

转载自blog.csdn.net/weixin_41802988/article/details/80221779