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多线程编程(五):死锁的形成
Apr 05 Python
Python文件及目录操作实例详解
Jun 04 Python
Python实现身份证号码解析
Sep 01 Python
Pythont特殊语法filter,map,reduce,apply使用方法
Feb 27 Python
Python实现并行抓取整站40万条房价数据(可更换抓取城市)
Dec 14 Python
pandas 获取季度,月度,年度首尾日期的方法
Apr 11 Python
python numpy 部分排序 寻找最大的前几个数的方法
Jun 27 Python
python使用多进程的实例详解
Sep 19 Python
Python数据报表之Excel操作模块用法分析
Mar 11 Python
Pandas删除数据的几种情况(小结)
Jun 21 Python
Django处理Ajax发送的Get请求代码详解
Jul 29 Python
opencv 查找连通区域 最大面积实例
Jun 04 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
hessian 在PHP中的使用介绍
2010/12/13 PHP
JS与PHP向函数传递可变参数的区别实例代码
2011/05/18 PHP
深入phpMyAdmin的安装与配置的详细步骤
2013/05/07 PHP
php读取二进制流(C语言结构体struct数据文件)的深入解析
2013/06/13 PHP
PHP临时文件的安全性分析
2014/07/04 PHP
php+mysql大量用户登录解决方案分析
2014/12/29 PHP
初识PHP中的Swoole
2016/04/05 PHP
用javascript添加控件自定义属性解析
2013/11/25 Javascript
Javascript:为input设置readOnly属性(示例讲解)
2013/12/25 Javascript
jQuery设置与获取HTML,文本和值的简单实例
2014/02/26 Javascript
提高NodeJS中SSL服务的性能
2014/07/15 NodeJs
15款jQuery分布引导插件分享
2015/02/04 Javascript
详细分析使用AngularJS编程中提交表单的方式
2015/06/19 Javascript
向JavaScript的数组中添加元素的方法小结
2015/10/24 Javascript
基于JS快速实现导航下拉菜单动画效果附源码下载
2016/10/27 Javascript
纯jQuery实现前端分页功能
2017/03/23 jQuery
vue父组件向子组件(props)传递数据的方法
2018/01/02 Javascript
vue cli构建的项目中请求代理与项目打包问题
2018/02/26 Javascript
js与jQuery实现获取table中的数据并拼成json字符串操作示例
2018/07/12 jQuery
layui问题之模拟table表格中的选中按钮选中事件的方法
2019/09/20 Javascript
JQuery+drag.js上传图片并且实现图片拖曳
2020/11/18 jQuery
javascript中闭包closure的深入讲解
2021/03/03 Javascript
[05:04]DOTA2上海特级锦标赛主赛事第二日TOP10
2016/03/04 DOTA
python端口扫描系统实现方法
2014/11/19 Python
Python程序运行原理图文解析
2018/02/10 Python
python机器学习之随机森林(七)
2018/03/26 Python
Scrapy使用的基本流程与实例讲解
2018/10/21 Python
python图形工具turtle绘制国际象棋棋盘
2019/05/23 Python
python实现拼图小游戏
2020/02/22 Python
scrapy框架携带cookie访问淘宝购物车功能的实现代码
2020/07/07 Python
如何利用pycharm进行代码更新比较
2020/11/04 Python
CSS3模拟动画下拉菜单效果
2017/04/12 HTML / CSS
欧洲有机婴儿食品最大的市场:Organic Baby Food(供美国和加拿大)
2018/03/28 全球购物
什么是聚集索引和非聚集索引
2012/01/17 面试题
会计专业个人求职信范文
2014/01/08 职场文书
幼儿园园长个人总结
2015/03/02 职场文书