Python通过队列来实现进程间通信的示例


Posted in Python onOctober 14, 2020

Python程序中,在进程和进程之间是不共享全局变量的数据的。

我们来看一个例子:

from multiprocessing import Process
import os
import time

nums = [11, 22]


def work1():
  """子进程要执行的代码"""
  print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))
  for i in range(3):
    nums.append(i)
    time.sleep(1)
    print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))


def work2():
  """子进程要执行的代码"""
  print("in process2 pid=%d ,nums=%s" % (os.getpid(), nums))


if __name__ == '__main__':
  p1 = Process(target=work1)
  p1.start()
  p1.join()

  p2 = Process(target=work2)
  p2.start()

进程 p1 里对全局变量 nums 循环进行处理,进程 p2 将 nums 打印出来,发现 nums 的值没有变化。

运行结果:

in process1 pid=5788 ,nums=[11, 22]
in process1 pid=5788 ,nums=[11, 22, 0]
in process1 pid=5788 ,nums=[11, 22, 0, 1]
in process1 pid=5788 ,nums=[11, 22, 0, 1, 2]
in process2 pid=11832 ,nums=[11, 22]

通过队列完成进程间通信

但是进程(Process)之间有时需要通信,操作系统提供了很多机制来实现进程间的通信。

可以使用 multiprocessing 模块的 Queue 实现多进程之间的数据传递。

Queue 本身是一个消息队列程序,首先用一个小实例来演示一下 Queue 的工作原理:

from multiprocessing import Queue
# 初始化一个Queue对象,最多可接收三条put消息
q = Queue(3) 
q.put("消息1")
q.put("消息2")
print(q.full()) # False
q.put("消息3")
print(q.full()) # True

# 因为消息队列已满下面的try都会抛出异常
# 第一个try会等待2秒后再抛出异常
try:
  q.put("消息4", True, 2)
except:
  print("消息队列已满,现有消息数量:%s" % q.qsize())
# 第二个Try会立刻抛出异常
try:
  q.put_nowait("消息4")
except:
  print("消息列队已满,现有消息数量:%s" % q.qsize())

# 推荐的方式,先判断消息列队是否已满,再写入
if not q.full():
  q.put_nowait("消息4")

# 读取消息时,先判断消息列队是否为空,再读取
if not q.empty():
  for i in range(q.qsize()):
    print(q.get_nowait())

运行结果:

Python通过队列来实现进程间通信的示例

队列 Queue 的使用说明

初始化 Queue()对象时(例如:q=Queue()),若括号中没有指定最大可接收的消息数量,或数量为负值,那么就代表可接受的消息数量没有上限(直到内存的尽头)。

Queue.qsize():返回当前队列包含的消息数量。

Queue.empty():如果队列为空,返回True,反之False。

Queue.full():如果队列满了,返回True,反之False。

Queue.get([block[, timeout]]):获取队列中的一条消息,然后将其从列队中移除,block 默认值为 True。

  1. 如果 block 使用默认值,且没有设置 timeout(单位秒),消息队列如果为空,此时程序将被阻塞,停在读取状态,直到从消息队列读到消息为止;如果设置了 timeout,则会等待 timeout 秒,若还没读取到任何消息,则抛出 "Queue.Empty" 异常。
  2. 如果 block 值为 False,消息列队如果为空,则会立刻抛出 "Queue.Empty" 异常。

Queue.get_nowait():相当 Queue.get(False)。

Queue.put(item,[block[, timeout]]):将 item 消息写入队列,block 默认值为 True。

  1. 如果 block 使用默认值,且没有设置 timeout(单位秒),消息队列如果已经没有空间可写入,此时程序将被阻塞,停在写入状态,直到从消息队列腾出空间为止;如果设置了timeout,则会等待 timeout 秒,若还没空间,则抛出 "Queue.Full" 异常。
  2. 如果 block 值为 False,消息队列如果没有空间可写入,则会立刻抛出 "Queue.Full" 异常。

Queue.put_nowait(item):相当Queue.put(item, False)。

Queue实例

我们以 Queue 为例,在父进程中创建两个子进程,一个往 Queue 里写数据,一个从 Queue 里读数据。

from multiprocessing import Process, Queue
import os
import time
import random


def write(q):
  # 写数据进程执行的代码:
  for value in ['A', 'B', 'C']:
    print('Put %s to queue...' % value)
    q.put(value)
    time.sleep(random.random())


def read(q):
  # 读数据进程执行的代码:
  while True:
    if not q.empty():
      value = q.get(True)
      print('Get %s from queue.' % value)
      time.sleep(random.random())
    else:
      break


if __name__ == '__main__':
  # 父进程创建Queue,并传给各个子进程:
  q = Queue()
  pw = Process(target=write, args=(q,))
  pr = Process(target=read, args=(q,))
  # 启动子进程pw,写入:
  pw.start()
  # 等待pw结束:
  pw.join()
  # 启动子进程pr,读取:
  pr.start()
  pr.join()
  print('')
  print('所有数据都写入并且读完')

运行结果:

Python通过队列来实现进程间通信的示例

以上就是Python通过队列来实现进程间通信的示例的详细内容,更多关于python实现进程间通信的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python计算牛顿迭代多项式实例分析
May 07 Python
python多线程socket编程之多客户端接入
Sep 12 Python
Python设计模式之工厂模式简单示例
Jan 09 Python
Python中的单继承与多继承实例分析
May 10 Python
Python smtplib实现发送邮件功能
May 22 Python
Python调用adb命令实现对多台设备同时进行reboot的方法
Oct 15 Python
在pandas多重索引multiIndex中选定指定索引的行方法
Nov 16 Python
python实现两张图片的像素融合
Feb 23 Python
详解Python数据分析--Pandas知识点
Mar 23 Python
python 梯度法求解函数极值的实例
Jul 10 Python
Python基于OpenCV实现人脸检测并保存
Jul 23 Python
Python多个装饰器的调用顺序实例解析
May 22 Python
python利用xlsxwriter模块 操作 Excel
Oct 14 #Python
如何解决python多种版本冲突问题
Oct 13 #Python
Django配置Bootstrap, js实现过程详解
Oct 13 #Python
Python文件操作及内置函数flush原理解析
Oct 13 #Python
Django如何实现防止XSS攻击
Oct 13 #Python
5款实用的python 工具推荐
Oct 13 #Python
Python内置函数及功能简介汇总
Oct 13 #Python
You might like
Win2003下APACHE+PHP5+MYSQL4+PHPMYADMIN 的简易安装配置
2006/11/18 PHP
首页四格,首页五格For6.0(GBK)(UTF-8)[12种组合][9-18][版主安装测试通过]
2007/09/24 PHP
php addslashes 函数详细分析说明
2009/06/23 PHP
PHP 的ArrayAccess接口 像数组一样来访问你的PHP对象
2010/10/12 PHP
php修改指定文件后缀的方法
2014/09/11 PHP
Mac OS下配置PHP+MySql环境
2015/02/25 PHP
使用Modello编写JavaScript类
2006/12/22 Javascript
Javascript实例教程(19) 使用HoTMetal(2)
2006/12/23 Javascript
javascript实现的listview效果
2007/04/28 Javascript
基于Jquery实现的一个图片滚动切换
2012/06/21 Javascript
向左滚动文字 js代码效果
2013/08/17 Javascript
jQuery的live()方法对hover事件的处理示例
2014/02/27 Javascript
js select下拉联动 更具级联性!
2020/04/17 Javascript
Jqprint实现页面打印
2017/01/06 Javascript
关于ES6的六个小特性(二)
2017/02/20 Javascript
浅谈JS如何实现真正的对象常量
2017/06/25 Javascript
浅析node Async异步处理模块用例分析及常用方法介绍
2017/11/17 Javascript
基于vue-cli vue-router搭建底部导航栏移动前端项目
2018/02/28 Javascript
简化vuex的状态管理方案的方法
2018/06/02 Javascript
vue集成kindeditor富文本的实现示例代码
2019/06/07 Javascript
echarts实现折线图的拖拽效果
2019/12/19 Javascript
Vue中axios拦截器如何单独配置token
2019/12/27 Javascript
JS highcharts动态柱状图原理及实现
2020/10/16 Javascript
解决vue初始化项目一直停在downloading template的问题
2020/11/09 Javascript
学Python 3的理由和必要性
2019/11/19 Python
Django实现文章详情页面跳转代码实例
2020/09/16 Python
Python如何在bool函数中取值
2020/09/21 Python
巴塞罗那观光通票:Barcelona Pass
2019/10/30 全球购物
MYSQL基础面试题
2012/05/13 面试题
财务副总经理工作职责
2013/11/25 职场文书
活动策划求职信模板
2014/04/21 职场文书
二年级评语大全
2014/04/23 职场文书
人事专员岗位职责说明书
2014/07/30 职场文书
销售开票员岗位职责
2015/04/15 职场文书
详解MySQL中的主键与事务
2021/05/27 MySQL
Java代码规范与质量检测插件SonarLint的使用
2022/08/05 Java/Android