进程间通信-笔记

进程间通信的方式:


a, 磁盘交互: 
b,Socket
c, 管道
d, 消息队列
e, 共享内存
f,信号
g,信号量


管道通信pipe: 


含义: 在内存中开辟一个空间,对2个进程都是可见的;从而实现信息传递;
需要导入Multiprocessing.pipe 方法

Pipe(duplex = True)    
    功能: 创建一个管道
    参数: duplex默认为True,表示双向管道;全双工
            False表示半双工,单向管道
    返回值: 返回两个管道流对象,表示管道的两端
            如果全双工,则两个管道流对象均可读写
            如果为单向管道,fd1只能读,fd2只能写

fd1.recv()
功能: 接收消息(每次接收1条)
参数:无
返回值: 接收到的消息
如果管道没有消息,则管道阻塞


fd2,send(data)
功能: 发送消息
参数:要发送的内容,可以不用转码
如果没有接收端,则管道破裂;
 

from multiprocessing import Process, Pipe
from time import sleep,ctime
import os


#创建管道,全双工
fd1,fd2 = Pipe(duplex=True)



def hello(name):
    print('os.getpid:',os.getpid())
    #发送消息给出去
    fd1.send('Hello World{}'.format(name))
    sleep(1)

p_mq = []
for I in range(5):
    p = Process(target = hello, args = (I,))
    p_mq.append(p)
    p.start()

#父进程接收子进程发过来的消息
for _ in range(5):
    msg = fd2.recv()
    print(msg)

#阻塞回收
for I in p_mq:
    I.join()

print('Over!!')

消息队列

顺序: 先进先出
定义: 在内存中开辟队列模型,用来存放消息。认可拥有队列的进程都可以存取消息

创建队列:
Queue(maxsize = 0) 
功能:创建一个消息队列
参数:maxsize 默认0,表示队列可存放消息由内存而定; 
     > 0 表示队列最多存放消息的条数
返回值: 返回消息队列对象


队列对象功能函数:
put(msg)    向队列中存放消息(字符串,证书,列表); 当队列满时会阻塞
full()        判断队列是否满,满True
empty()        判断队列是否为空,空返回True
qsize()        得到当前队列中消息个数
get()        取出一条消息
close()     关闭队列

注意: put()  get() 中均有可选参数block和timeout
    block 默认为True表示阻塞函数,如果设置为False则不阻塞
    multiprocessing中创建的子进程,无法使用put();进程池也不可以,fork创建的子进程可以
    

from multiprocessing import Queue,Process
from time import sleep

q = Queue(10)
I = 0
while not q.full():
    msg = 'Game' + str(I)
    q.put(msg,False)
    I += 1

while not q.empty():
    print('msg:',q.get(False))
    print('剩余队列长度:',q.qsize())
from multiprocessing import Queue
from multiprocessing import Process
from time import sleep

q = Queue()


def fun1():
    sleep(1)
    q.put('this is process 1')


def fun2():
    sleep(2)
    print('message:',q.get())


p1 = Process(target=fun1)

p2 = Process(target=fun2)

p1.start()
p2.start()
p1.join()
p2.join()

共享内存

在内存中开辟一段空间,存储数据,对多个进程可见。每次写入共享内存的数据都从固定位置开始,会覆盖之前的内容,读取速度最快

from multiprocessing import Value, Array

obj = Value(ctype,obj)
功能: 开辟共享内存空间
参数: ctype: str    要转变的c类型;所开辟的共享内存空间接收c语言的格式;(对照ctype表)
        obj: 初始值
返回值: 一个共享内存对象
        
obj = Array(ctype,obj)
功能: 开辟共享内存空间
参数: ctype 要转换的类型;
        obj:存入到共享内存的数据; 
            列表: 要求数据类型一致
            正整数: 表示要开辟多大的序列空间

返回值: 一个共享内存对象    

from multiprocessing import Process, Value, Array
import random
from time import sleep

def deposite(money):
    for _ in range(100):
        sleep(0.01)
        money.value += random.randint(1,200)

def withdraw(money):
    for _ in range(100):
        sleep(0.01)
        money.value -= random.randint(1,200)

money = Value('i',2000)


p1 = Process(target= deposite,args=(money,))
p2 = Process(target= withdraw, args=(money,))

p1.start()
p2.start()

p1.join()
p2.join()

print(money.value)

比较:

 管道内存消息队列共享内存
开辟空间内存内存内存
读写方式双向/单向FIFO(先进先出)覆盖内存
效率一般一般
应用多用于情缘进程方便灵活,广泛较为复杂
是否需要互斥机制需要

 信号

一个进程向另一个进程传递特定信息 ,查看信号kill -l

 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

信号名称: 系统定义,信号的名字
信号含义: 系统定义,信号的作用
信号的默认处理方法: 系统定义,信号给接收进程带来的行为,一般有终止,暂停,忽略


重点的几个信号: 
SIGINT: 该信号在用户输入INTR字符(通常是Ctrl-C)时发出,终端驱动程序发送该信号并送到前台进程中的每一个进程
         默认操作: 终止

SIGQUIT: 该信号和SIGINT 类似,但由QUIT字符(通常是Ctrl-\)来控制
        默认操作: 终止
    
SIGKILL: 该信号用来立即结束程序的运行,并且不能被阻塞、处理和忽略。 
        默认操作: 终止

SIGALARM:该信号当一个定时器到的时候发出    
        默认操作: 终止

SIGSTOP:    该信号用于暂停一个进程,且不能被阻塞、处理或忽略。    
        默认操作: 暂停进程
        
SIGTSTP:    该信号用于暂停交互进程,用户可以键入SUSP字符(通常是Ctrl-Z)发出这个信号
        默认操作: 暂停进程
        
SIGCHLD:    子进程改变状态时,父进程会受到这个信号
        默认操作:忽略
 发送:
    os.kill(pid,sig)
    功能: 向一个进程发送信号
    参数: pid: 要发送信号的进程
            sig:信号

import os
import signal
os.kill(24051,signal.SIGKILL)

signal.alarm(sec)
功能: 想自身发送一个时钟信号 SIGALRM
参数: 秒
    

import signal
from time import sleep

signal.alarm(4)
signal.alarm(8)

while True:
    sleep(1)
    print('waiting')

注意:信号属于异步通信方式,信号的发送不会影响程序的持续进行
      在一个进程中只能同时有一个时钟,后面时钟会覆盖前面时钟
      
    
signal.pause()     
功能: 阻塞等待一个信号的发生
         

信号处理:
    signal.signal(signum, handler)
    功能: 处理一个信号
    参数: signum: 要处理的信号
            handler: 对该信号的处理方法
                    SIG_DFL    默认处理方法
                    SIG_IGN: 忽略该信号
                    func:  调用该函数; 回调函数 ;采用自定义方法处理
                    
    signal函数是一个异步处理信号函数,只要执行,在进程中就会按照指定方法处理信号
    signal 不能处理SIGSTOP, SIGKILL信号

cookie    
使用处理僵尸进程,除了:wait,waitpid还有信号处理方式
在父进程中忽略子进程的发送信号即可: signal(SIGCHLD,SIG_IGN)
 

import signal
from time import sleep

signal.alarm(4)
signal.signal(signal.SIGALRM, signal.SIG_IGN)
signal.signal(signal.SIGINT, signal.SIG_IGN)


while True:
    sleep(1)
    print('waiting')


作业:
    1,对进程间通信方式进行描述联系
    2, 熟悉进程间通信代码

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值