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解析模块(ConfigParser)使用方法
Dec 10 Python
Python3实现的反转单链表算法示例
Mar 08 Python
Python画图实现同一结点多个柱状图的示例
Jul 07 Python
Django的models模型的具体使用
Jul 15 Python
python判断单向链表是否包括环,若包含则计算环入口的节点实例分析
Oct 23 Python
基于Python中的yield表达式介绍
Nov 19 Python
简单了解pytest测试框架setup和tearDown
Apr 14 Python
Python matplotlib实时画图案例
Apr 23 Python
Python使用os.listdir和os.walk获取文件路径
May 21 Python
python图片验证码识别最新模块muggle_ocr的示例代码
Jul 03 Python
Python把图片转化为pdf代码实例
Jul 28 Python
Python实现日志实时监测的示例详解
Apr 06 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
php ob_flush,flush在ie中缓冲无效的解决方法
2010/05/09 PHP
PHP按行读取文件时删除换行符的3种方法
2014/05/04 PHP
PhpStorm 如何优雅的调试Hyperf的方法步骤
2019/11/24 PHP
自动完成JS类(纯JS, Ajax模式)
2009/03/12 Javascript
关于JavaScript中原型继承中的一点思考
2012/07/25 Javascript
javascript圆盘抽奖程序实现原理和完整代码例子
2014/06/03 Javascript
jQuery支持动态参数将函数绑定到事件上的方法
2015/03/17 Javascript
js实现接收表单的值并将值拼在表单action后面的方法
2015/11/23 Javascript
深入理解Java线程编程中的阻塞队列容器
2015/12/07 Javascript
基于jQuery实现鼠标点击导航菜单水波动画效果附源码下载
2016/01/06 Javascript
微信小程序 es6-promise.js封装请求与处理异步进程
2017/06/12 Javascript
详解webpack3编译兼容IE8的正确姿势
2017/12/21 Javascript
使用vue-router设置每个页面的title方法
2018/02/11 Javascript
Swiper 4.x 使用方法(移动端网站的内容触摸滑动)
2018/05/17 Javascript
取消Bootstrap的dropdown-menu点击默认关闭事件方法
2018/08/10 Javascript
jquery分页优化操作实例分析
2019/08/23 jQuery
vue选项卡切换登录方式小案例
2019/09/27 Javascript
Python实现计算文件夹下.h和.cpp文件的总行数
2015/04/23 Python
小白入门篇使用Python搭建点击率预估模型
2018/10/12 Python
Python PO设计模式的具体使用
2019/08/16 Python
GDAL 矢量属性数据修改方式(python)
2020/03/10 Python
Python ORM框架Peewee用法详解
2020/04/29 Python
pytho matplotlib工具栏源码探析一之禁用工具栏、默认工具栏和工具栏管理器三种模式的差异
2021/02/25 Python
美国网上花店:JustFlowers
2017/02/12 全球购物
美国女性运动零售品牌:Lady Foot Locker
2017/05/12 全球购物
Uber Eats台湾:寻找附近提供送餐服务的餐厅
2018/05/07 全球购物
Linden Leaves官网:新西兰纯净护肤品
2020/12/20 全球购物
学校后勤人员职责
2013/12/27 职场文书
学期自我评价
2014/01/27 职场文书
2014年五四青年节演讲稿范文
2014/04/22 职场文书
教师作风整顿个人剖析材料
2014/10/10 职场文书
80后婚前协议书范本
2014/10/24 职场文书
2015年毕业生实习评语
2015/03/25 职场文书
2015年幼儿园班务工作总结
2015/05/12 职场文书
pytorch 实现多个Dataloader同时训练
2021/05/29 Python
Python中json.load()和json.loads()有哪些区别
2021/06/07 Python