43_Python_多任务编程--进程间的通信

本文介绍了Python中实现多任务编程的几种通信方式,包括管道通信Pipe、消息队列、信号、共享内存、信号量等。通过实例展示了如何使用这些通信机制进行进程间的交互和数据传递,帮助理解Python多进程编程中的同步和互斥概念。
摘要由CSDN通过智能技术生成

一、简介

   进程间由于空间独立,资源无法互相直接获取,此时在不同的进程间进行数据传递就需要专门的通信方法。进程间通信的方法包含以下6种,本文将依次进行介绍:

在这里插入图片描述

在这里插入图片描述

二、管道通信Pipe

在内存中开辟一段内存空间、形成管道结构。管道对多个进程可见,进程可以对管道进行读写操作
from multiprocessing import Pipe
fd1,fd2=Pipe(duplex=True)
功能:创建一个管道
参数:默认为双向管道,如果设置为False,则为单向管道
返回值:对于双向管道fd1,fd2都可以进行读写操作;单相管道,fd1只可读,fd2只能写
读写操作:
fd.recv()–>从管道读取内容;返回值为读取的内容;如果管道无内容,则阻塞;
fd.send()–>向管道写入内容;参数为发送的内容;几乎可以发送所有Python支持的数据

三、消息队列

可以使⽤multiprocessing模块的Queue实现多进程之间的数据传递,Queue 本身是⼀个消息列队程序。

Queue.qsize(): 返回当前队列包含的消息数量;
Queue.empty(): 如果队列为空,返回True,反之False ;
Queue.full(): 如果队列满了,返回True,反之False;

Queue.get([block[, timeout]]):
获取队列中的⼀条消息,然后将其从列队中移除,block默认值为True;
Queue.get_nowait():
相当Queue.get(False);
Queue.put(item,[block[, timeout]]):
将item消息写⼊队列,block默认值 为True;
Queue.put_nowait(item):
相当Queue.put(item, False)

拓展: 请使用实例化对象的方式实现消息队列的通信方式.

四、信号

1、一个进程向另一个进程通过信号传递某种讯息,接收方在接收到信号后进行相应的处理;
【1】LINUX终端:
kill -l 查看信号名称和编号
` kill -signum PID 给PID的进程发送一个信号
(eg:kill -9 进程号 #杀死一个进程)
【2】程序执行的同步和异步
同步:按照步骤一步一步顺序执行
异步:在程序执行中利用内核,不影响应用层程序持续执行
信号是唯一的异步通信方式
【3】关于信号
信号名称:kill -l查看到的名称或编号
信号含义:信号的作用
默认行为:当一个进程接收到信号时采取的行为(终止进程,暂停进程,忽略产生)
e.g.

            SIGHUP   终端断开
		    SIGINT   ctrl + c
		    SIGQUIT  ctrl + \
		    SIGTSTP  ctrl + z
		    SIGKILL  终止进程且不能被处理
		    SIGSTOP  暂停进程且不能被处理
		    SIGALRM  时钟信号
		    SIGCHLD  子进程状态改变发给父进程

【4】通过Python进行信号处理:

os.kill(pid,sig)
功能:发送信号给某个进程
参数:pid 给哪个进程发送信号
sig:要发送什么信号
signal.alarm(sec)
功能:一定时间后给自身发送一个slgalrm信号
参数:指定时间
##一个进程只能设置一个时钟,第二个时钟会覆盖之前的时间

signal.pause()
功能:阻塞等待一个信号的发生

signal.signal(signum,handler)
功能:处理信号
参数: signum:要处理的信号
handler:信号处理的方法包含以下三种:
SIG_DFL 使用默认方法处理
SIG_IGN 忽略这个信号
func 自定义函数处理信号
def func(sig,frame):
“sig—表示要处理的信号;frame——信号的结构对象”

			*signal函数是一个异步处理函数
			*signal函数不能处理SIDSTOP信号
			*在父进程中使用signal(SIGCHLD,SLG——IGN),这样子进程退出时会交给系统处理,是解决僵尸进程的惯用手法

五、共享内存

在内存中开辟一段空间,存储数据,对于多个进程可见。每次写入共享内存中的数据会覆盖之前的内容
【1】使用Value创建共享内存
obj =Value(ctype,obj)
功能:开辟共享内存空间
参数: ctype 字符串 要转变的c的数据类型
obj 共享内存的初始化数据
返回:共享内存对象

	obj.value     	表示共享内存中的值。对其修改或者使用即可

【2】使用Array创建共享内存
obj = Array(ctype,obj)
功能:开辟共享内存
参数:ctype 字符串 要转变的c的数据类型
obj 共享内存的初始化数据
1、列表:将列表存入共享内存,数据类型一致
2、正整数:表示开辟几个数据空间

六、信号量

给定一定的数量,对多个进程可见并且多个进程根据信号量的多少确定不同的行为(可用于操作共享的有限资源)
multiprocessing —> Semaphore()
sem = Semaphore(num)
功能:生成信号量对象
参数: 信号量的初始值
返回值: 信号量对象

sem.acquire()   信号量数量减1  信号量为0时会阻塞
sem.release()   信号量数量加1
sem.get_value() 获取当前信号量的值

七、本地套接字

	linux进程间通信还可以使用socket本地套接字,socket函数的第一个参数设置为socket.AF_UNIX表示创建本地套接字;使用方法类似与socket网络编程。此处不在论述。

八、同步互斥机制

目的:解决对共有资源操作产生的争夺
临界资源:多个进程或者线程都能够操作的资源
临界区:操作临界资源的代码段
同步:是一种合作关系,为完成某个任务,多进程或多线程之间形成的一种协调。按照约定依次执行对临界资源的操作,相互告知相互促进。
互斥:互斥是一种制约关系,当一个进程占有临界资源就会进行加锁的操作,此时其他进程就无法操作该临界资源。直到使用的进程进行解锁操作后才能使用

Python中通过Event事件或Lock锁实现同步互斥机制:
1.Event

        multiprocessing ---> Event
        e = Event()         #创建事件对象
        e.wait([timeout])   #事件阻塞
        e.set()             #当e被set后,e.wait不再阻塞
        e.clear()           #当e被clear后,e.wait又会阻塞
        e.is_set()          #事件判断 判断当前事件对象是否被设置

    2.Lock

        multiprocessing ---> Lock
        lock = Lock()
        lock.acquire()   #上锁
        lock.release()   #解锁

        *上锁状态执行acquire()操作会阻塞
        *解锁状态执行acquire()不阻塞

        使用上下文管理器实现:

            lock = multiprocessing.Lock()
            with  lock:--->上锁
               ...
               --->with代码段结束即解锁
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值