进程间通信(IPC)

  • 进程间通信(IPC)

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

    进程间通信方法: 管道 ,消息队列 ,共享内存, 信号, 信号量, 套接字

    管道通信(Pipe)
        通信原理:在内存中开辟管道空间生成管道操作对象,多个进程使用'同一个'管道对象进行操作,即可实现通信

        multiprocessing --->Pipe

        fd1,fd2 = Pipe(duplex = True)

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

        fd.recv()
        功能:从管道读取信息
        返回值:读取到的内容没有参数

        *如果管道内容为空则阻塞

        fd.send(data)
        功能:向管道写入内容
        参数: 要写入的内容

        *可以发送python数据类型

# pipe.py
from multiprocessing import Process, Pipe
import os, time

# 创建管道对象
fd1, fd2 = Pipe()


def fun(name):
    time.sleep(3)
    # 向管道写入内容
    fd2.send(123456)


jobs = []

for i in range(4):
    p = Process(target = fun, args = (i,))
    jobs.append(p)
    p.start()
for i in range(4):
    # 读取管道
    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])
        功能:获取队列信息
        参数:data要存的内容
            block 默认队列空时会阻塞,设置为False则非阻塞
            timeout 超时时间
        返回值:返回取出的内容

        q.full() :判断队列是否为满
        q.empty():判断队列是否为空
        q.qsize():判断队列中消息数量
        q.close():关闭队列

# queue2.py
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()


# 收到消息: {'a': 1, 'b': 2}

    共享内存

        通信原理:在内存中开辟一块空间,对多个进程可见,进程可以写入输出,但是每次写入的内容会覆盖之前的内容
        obj = Value(ctype,obj)
        功能:开辟共享内存空间
        参数:ctype 要存储的数据类型
            obj 共享内存的初始化数据
        返回:共享内存对象
        obj.value 即为共享内存值,对其修改即修改共享内存


        obj = Array(ctype, obj)
        功能:开辟共享内存空间
        参数:ctype 要存储的数据格式
                 obj 初始化存入的内容 比如:列表, 字符串
                 如果是数字则表示开辟空间的个数
        返回值:返回共享内存对象

        *可以通过遍历获取每一个元素的值
        eg. [1,2,3]---->obj[1] == 2
        *如果存入的是字符串
        obj.value 表示字符串的首地址
                           管道             消息队列     共享内存

        开辟空间   内存               内存              内存

        读写方式  两端读写     先进先出   覆盖之前内容
                          双向/单向
        效率           一般                一般            较高

        应用     多用于父进程    广泛灵活     需要注意
                                              进行互斥操作

# value.py
from multiprocessing import Process, Value
import time 
import random 

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


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


# 取钱
def withdraw():
    for i in range(100):
        time.sleep(0.04)
        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)

    信号通信        
        一个进程向另一个进程发送一个信号来传递某种讯息,接受者根据接受到的某种信号进行相应的行为

        kill -l   查看系统信号
        kill -sig PID  向一个进程发送信号

        关于信号
        信号名称    信号含义     默认处理方法
        SIGHUP     连接断开
        SIGINT       CTRL-C
        SIGQUIT    CTRL-Z
        SIGSTP      终止一个进程
        SIGKILL      暂停一个进程
        SIGALRM   时钟信号
        SIGCHLD  子进程状态改变时给父进程发出
   
        python 发送信号

        signa1

        os.kill(pid, sig)
        功能:发送信号
        参数: pid 目标进程
              sig 要发送的信号

# signal_1.py
from signal import *
import time


def handler(sig,frame):
    if sig == SIGALRM:
        print('接收到时钟信号')
    elif sig == SIGINT:
        print('就不结束')

alarm(5)

signal(SIGALRM, handler)
signal(SIGINT, handler)

while True:
    print('waiting for a signal')
    time.sleep(2)

# waiting for a signal
# waiting for a signal
# waiting for a signal
# 接收到时钟信号
# waiting for a signal
# waiting for a signal
# waiting for a signal
# waiting for a signal
# ^C就不结束
# waiting for a signal
# ^C就不结束
# ^C就不结束
# waiting for a signal
# ^\退出 (核心已转储)
# kill.py
import os
import signal
# 向51405 发送信号
os.kill(51405, signal.SIGKILL)

信号的使用

import signal
signal.alarm(sec)

    功能: 向自身发送时钟信号-->SIGALRM
    参数: sec 时钟时间
    *进程中只能有一个时钟,第二个会覆盖第一个时间         

    同步执行:按照顺续逐步执行,一步完成再做下一步
    异步执行:在执行过程中利用内核记录延迟繁盛或者准备处理的事件,这样不影响应用层的持续         执行.当事件发生时,再由内核告知应用层处理

    *信号是唯一的异步通信方法

signal.pause()
    功能:阻塞等待接受一个信号

signal.signal(signum, handler)
    功能:处理信号
    参数:signum  要处理的信号
        handler 信号的处理方法
            SIG_DFL  表示使用默认的方法处理
            SIG_IGN  表示忽略这个信号
            func     传入一个函数表示用指定函数处理
                def func(sig, frame)
                    sig:捕获到的信号
                    frame:信号的对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值