多进程间通信

管道通信:

在内存中开辟一块空间,对多个进程可见,通过管道进程进行通信

 

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()

功能:阻塞等待一个信号的发生

 

posted @ 2019-07-08 10:47  sike8  阅读(327)  评论(0编辑  收藏  举报