多进程间通信
管道通信:
在内存中开辟一块空间,对多个进程可见,通过管道进程进行通信
multiprocessing ----->Pipe
Pipe(duplex=True)
功能:创建一个管道
参数:duplex默认为True 表示双向管道
设置为False 则表示单向管道(fd1只能recv;fd2只能send)
返回值:返回两个管道流对象,表示管道的两端
如果是双向管道则两侧均可以读写
如果为单向管道,则fd1只能读,fd2只能写
接受消息 fd1.recv()
==========================================
功能:接收消息(每次接收一条)
参数:无
返回值:接收到的消息
*如果管道没有消息,会阻塞
发送消息 fd2.send(data)
=============================================
功能:发送消息 可以是字符串或其他类型
参数:要发送的内容
*如果没有接收端,则管道破裂
from multiprocessing import Process,Pipe import os,time #创建一个双向管道 fd1,fd2=Pipe() def fun(name): time.sleep(1) #发字符串到管道 fd1.send("hello"+str(name)) print(os.getppid(),"-------",os.getpid()) print('=='*10) jobs=[] for i in range(5): p=Process(target=fun,args=(i,)) jobs.append(p) p.start() #接收子进程发送的消息 for i in range(5): data=fd2.recv() print('主程序接收:',data) for i in jobs: i.join()
yangrui@ubuntu:~/num6$ python3 pipe.py 23917 ------- 23919 23917 ------- 23920 ==================== ==================== 主程序接收: hello0 主程序接收: hello1 主程序接收: hello4 23917 ------- 23923 ==================== 23917 ------- 23921 ==================== 主程序接收: hello2 23917 ------- 23922 ==================== 主程序接收: hello3 yangrui@ubuntu:~/num6$
消息队列
队列:先进先出
在内存中开辟队列模型,用来存放消息,任何拥有队列进程都可以存取消息
创建队列
q=Queue(maxsize=0)
功能:创建一个消息队列
参数:maxsize默认为0,表示队列可存放消息由内存而定
>0 表示队列最多存放多少条消息
返回值:返回消息队列对象
q.put()
功能:向队列中存放消息
参数:要存放的消息(字符串,整数,列表)
*当队列满时会阻塞
q.full()
判断队列是否为满 ,如果满返回True
q.get()
功能:向队列中取出消息
返回值:取出的消息
*当队列空时会阻塞
q,empty()
判断队列是否为空,空返回True
q,qsize()
得到当前队列中消息的个数
q.close()
关闭队列
*put get中均有可选参数 block和timeout
block默认为True表示阻塞函数;如果设置为False则不阻塞
timeout block 为True时,设置超时时间
共享内存:
在内存中开辟一块空间,存储数据,对多个进程可见;
每次写入共享内存的数据会覆盖之前的内容;
由于对内存格式化较少,所以存取速度快
from multiprocessing import Value,Array
obj=Value(ctype,obj)
功能:开辟共享内存空间
参数:ctype str 要转变的c语言类型
obj 写入共享内存的初始值
返回值:返回一个共享内存对象
obj.value即可得到共享内存中的值
from multiprocessing import Value,Process import time import random #向共享内存存钱 def deposite(money): for i in range(100): time.sleep(0.02) money.value+=random.randint(1,200) #从共享内存取钱 def withdraw(money): for i in range(100): time.sleep(0.02) money.value-=random.randint(1,100) #创建共享内存对象 money=Value("i",2000) #i表示ctype,对应表格中的的“int”类型 d=Process(target=deposite,args=(money,)) w=Process(target=withdraw,args=(money,)) d.start() w.start() d.join() w.join() print(money.value)
obj=Array(ctype,obj)
功能:开辟共享内存空间
参数:ctype 要转换的类型
obj 存入到共享内存中的数据类型
是一个列表,要求列表中数据类型一致
正整数,则表示开辟一个多大的序列空间
返回值:一个共享内存对象
from multiprocessing import Array,Process import time def fun(shm): for i in shm: print(i) #在子进程中修改共享内存空间传入的值 shm[2]=100 #开辟共享共享内存空间,可容纳6个整数 #初始值[1,2,3,4,5,6] shm=Array("i",[1,2,3,4,5,6]) p=Process(target=fun,args=(shm,)) p.start() p.join() ##在子进程中修改共享内存空间传入的值后,主进程得到的值 #是改变后的,从而验证共享内存空间值覆盖特征 for i in shm: print(i)
yangrui@ubuntu:~/num6$ python3 array.py
1
2
3
4
5
6
1
2
100
4
5
6
上述代码修改为:
#表示在共享内存中开辟一个包含6个整形的空间
shm=Array('i',6)
yangrui@ubuntu:~/num6$ python3 array.py 0 0 0 0 0 0 0 0 100 0 0 0
信号
一个进程向另外一个进程通过信号传递某种信息
kill -l 查看信号
kill -signame PID 给PID的进程发送一个信号
关于信号:
信号名称:系统定义,信号的名称
信号的含义:系统定义,信号的作用
信号的默认处理方法:系统定义,信号给接收进程带来的行为。一般有终止、暂停、忽略
python如何操作信号
发送:
os.kill(pid,sig)
功能:向一个进程发送一个信号
参数:pid:要发送信号的进程PID
sig:要发送的信号
signal.alarm(sec)
功能:向自身发送一个时钟信号 SIGALRM
参数:sec时钟秒数
**信号属于异步通信方式,信号的发送不会影响进程的持续执行。见下图;
=============================================
一个进程中只能同时有一个时钟,后面的时钟会覆盖前面的
============================================
signal.pause()
功能:阻塞等待一个信号的发生