Python进程间的通信一起来了解下
作者:程序猿-张益达 发布时间:2022-10-27 01:41:30
通信方式
进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块主要通过队列方式
队列:队列类似于一条管道,元素先进先出
需要注意的一点是:队列都是在内存中操作,进程退出,队列清空,另外,队列也是一个阻塞的形态
Queue介绍:
创建队列的类(底层就是以管道和锁定的方式实现):
Queue([maxsize]):创建共享的进程队列,Queue是多进程安全的队列,
可以使用Queue实现多进程之间的数据传递。maxsize是队列中允许最大项数,省略则无大小限制。
方法介绍:
def put(self, obj, block=True, timeout=None):插入数据到队列中
Block值默认为True,代表当队列已满时,会阻塞。如果block为False,则队列满会报异常Queue.Full
timeout表示会阻塞到指定时间,直到有剩余的空间供插入,如果时间超时,则报异常Queue.Full
def get(self, block=True, timeout=None):从队列中取出数据
Block值默认为True,代表当队列为空时,会阻塞。如果block为False,则队列空会报异常Queue.Empty
timeout表示会等待到指定时间,直到取出数据,如果时间超时,则报异常Queue.Empty
def empty(self): 判断队列是否为空,如果空返回True
def full(self): 判断队列是否已满,如果满返回True
def qsize(self): 返回队列的大小
应用举例:
from multiprocessing import Process, Manager
q = Manager().Queue(2)
q.put(1)
q.put(2,block=False,timeout=2)
def func():
print(q.get())
p = Process(target=func)
print("size",q.qsize())
print("full",q.full())
p.start()
p.join()
print("empty",q.empty())
print("get", q.get())
print("get", q.get(block=False,timeout=2))
输出结果
生产者和消费者模型
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。
为什么要使用生产者和消费者模式
在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。
什么是生产者消费者模式
生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯:
生产者,只需要往队列里面丢东西(生产者不需要关心消费者)
消费者,只需要从队列里面拿东西(消费者也不需要关心生产者)
阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。
实现方式一:Queue
from multiprocessing import Process,Manager,active_children
import random
import queue
import time
class Producer(Process):
def __init__(self,queue):
super().__init__()
self.queue = queue
def run(self):
for i in range(6):
r = random.randint(0, 99)
time.sleep(1)
self.queue.put(r)
print("add data{}".format(r))
class Consumer(Process):
def __init__(self,queue):
super().__init__()
self.queue = queue
def run(self):
while True:
if not self.queue.empty():
data = self.queue.get()
print("minus data{}".format(data))
if __name__ == '__main__':
q = Manager().Queue() # 创建队列
p = Producer(q)
c = Consumer(q)
p.start()
c.start()
print(active_children()) # 查看现有的进程
p.join()
c.join()
print("结束")
实现方式二:利用JoinableQueue
JoinableQueue([maxsize]):一个Queue对象,但队列允许项目的使用者通知生成者项目已经被成功处理。通知进程是使用共享的信号和条件变量来实现的。
JoinableQueue的实例除了与Queue对象相同的方法之外还具有:
task_done():使用者使用此方法发出信号,表示get()的返回项目已经被处理。如果调用此方法的次数大于从队列中删除项目的数量,将引发ValueError异常
join():生产者调用此方法进行阻塞,直到队列中所有的项目均被处理。阻塞将持续到队列中的每个项目均调用task_done()方法为止
from multiprocessing import Process,JoinableQueue
import os
import time
import random
def print_log(msg, log_type="prod"):
if log_type == 'prod':
print("\033[32;1m%s\033[0m" %msg)
elif log_type == 'con':
print("\033[31;1m%s\033[0m" %msg)
def producer(q):
"""
生产者
:param q:
:return:
"""
for i in range(10):
data = random.randint(1,200)
time.sleep(2)
q.put(data) # 放入队列
msg = "add data {}".format(data)
print_log(msg)
q.join() # 生产者调用此方法进行阻塞,直到队列中所有的项目均被处理。
# 阻塞将持续到队列中的每个项目均调用q.task_done()方法为止
def consumer(q):
"""
消费者
:param q:
:return:
"""
while True:
if not q.empty():
time.sleep(5)
data = q.get()
msg = "minus data{}".format(data)
print_log(msg,"con")
q.task_done() # q.get()的返回项目已经被处理
if __name__ == '__main__':
q = JoinableQueue()
prod = Process(target=producer, args=(q,))
con = Process(target=consumer, args=(q,))
con.daemon = True # 设置为守护进程,但是不用担心,producer内调用q.join保证了consumer已经处理完队列中的所有元素
# 开启进程
prod.start()
con.start()
prod.join() # 等待生产和消费完成,主线程结束
print("结束")
输出结果
来源:https://blog.csdn.net/weixin_41951954/article/details/123331551


猜你喜欢
- 这篇文章主要介绍了Python sqlite3查询操作过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,
- 首先一起来复习一下死锁的概念:死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。下面我们通过几
- 使用opencv自带的模板匹配1、目标匹配函数:cv2.matchTemplate()res=cv2.matchTemplate(image
- 关于浏览器的最离奇的统计结果之一就是Internet Explorer 版本6,7和8共存。截至本文,Internet Explorer各个
- 网页颜色变黑白代码国务院决定,为表达全国各族人民对青海玉树地震遇难同胞的深切哀悼,2010年4月21日举行全国哀悼活动,全国和驻外使领馆下半
- 首先我们要在邮箱的设置中开通那个POP3然后我们要导入这些包import poplibfrom datetime import dateti
- 前言最近做了几个简单的爬虫python程序,于是就想做个窗口看看效果。首先是,窗口的话,以前没怎么接触过,就先考虑用Qt制作简单的ui。这里
- 一 什么是WebsocketWebSocket是一种在单个TCP连接上进行全双工通信的协议WebSocket使得客户端和服务器之间的数据交换
- 前言最近在学习python,发现一个微信自动发消息的小demo感觉很有意思,试了一下,不成功,因为demo中用的是itchat这个库来操作微
- 为什么要将MySQL数据库必须运行在“普通用户”的状态下呢?与MSSQL SERVER一样,因为如果使用了“超级管理员”或者“本地系统用户”
- WAP站点,这似乎是一个有点落伍的东西。在诞生之初,它很简陋,只能通过一个叫WML的标记语言来搭建没有任何美感的文字+链接页面。而今,绝大部
- 如下所示:import jsonresult = response.read()result.decode('utf-8')
- 本文实例讲述了Python实现的网页截图功能。分享给大家供大家参考,具体如下:方法一、使用PyQt4的QtWebKit组件#!/usr/bi
- 1.将以下代码加入到HEML的<body></body>之间<SCRIPT language=jav
- 先解释一下这篇Blog延期的原因,本来已经准备好了全部内容,但是当我重新回顾实例三的时候,发现自己还是存在认知不足的地方,于是为了准确表述,
- 1 将文件保存到服务器本地upload.html<!DOCTYPE html><html lang="en&qu
- Mac 安装 Python3.10 并且配置环境一、Python的安装访问官网:https://www.python.org/选择系统(Ma
- 最长公共子序列python实现,最长公共子序列是动态规划基本题目,下面按照动态规划基本步骤解出来。1.找出最优解的性质,并刻划其结构特征序列
- 讲这个方法之前,我们应该先了解下插入节点时浏览器会做什么。在浏览器中,我们一旦把节点添加到document.body(或者其他节点)中,页面
- matplotlib官方除了提供了鼠标十字光标的示例,还提供了同一图像内多子图共享光标的示例,其功能主要由widgets模块中的MultiC