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中操作时间之strptime()方法的使用
Dec 30 Python
5种Python单例模式的实现方式
Jan 14 Python
Python使用正则表达式抓取网页图片的方法示例
Apr 21 Python
VSCode下好用的Python插件及配置
Apr 06 Python
Python 数据处理库 pandas进阶教程
Apr 21 Python
python学生管理系统开发
Jan 30 Python
深入解析python中的实例方法、类方法和静态方法
Mar 11 Python
python3 打印输出字典中特定的某个key的方法示例
Jul 06 Python
浅谈在JupyterNotebook下导入自己的模块的问题
Apr 16 Python
python3 简单实现组合设计模式
Jul 02 Python
Pycharm编辑器功能之代码折叠效果的实现代码
Oct 15 Python
Python实现迪杰斯特拉算法并生成最短路径的示例代码
Dec 01 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页面运行时间的函数介绍
2013/07/01 PHP
php中引用符号(&)的使用详解
2013/11/13 PHP
ThinkPHP的MVC开发机制实例解析
2014/08/23 PHP
php支持中文字符串分割的函数
2015/05/28 PHP
php通过PHPExcel导入Excel表格到MySQL数据库的简单实例
2016/10/29 PHP
PHP实现无限分类的实现方法
2016/11/14 PHP
ie 调试javascript的工具
2009/04/29 Javascript
javascript下判断一个元素是否存在的代码
2010/03/05 Javascript
jQuery的实现原理的模拟代码 -1 核心部分
2010/08/01 Javascript
js 编程笔记 无名函数
2011/06/28 Javascript
JavaScript单元测试ABC
2012/04/12 Javascript
jquery提交form表单时禁止重复提交的方法
2014/02/13 Javascript
浅析JavaScript基本类型与引用类型
2014/05/28 Javascript
Javascript之Math对象详解
2016/06/07 Javascript
javascript 闭包详解及简单实例应用
2016/12/31 Javascript
js获取当前周、上一周、下一周日期
2017/03/19 Javascript
JS按条件 serialize() 对应标签的使用方法
2017/07/24 Javascript
前端防止用户重复提交js实现代码示例
2018/09/07 Javascript
在vue项目实现一个ctrl+f的搜索功能
2020/02/28 Javascript
python使用marshal模块序列化实例
2014/09/25 Python
Python访问纯真IP数据库脚本分享
2015/06/29 Python
Python 中开发pattern的string模板(template) 实例详解
2017/04/01 Python
Python常用时间操作总结【取得当前时间、时间函数、应用等】
2017/05/11 Python
python 实现GUI(图形用户界面)编程详解
2019/07/17 Python
python 实现视频 图像帧提取
2019/12/10 Python
python与pycharm有何区别
2020/07/01 Python
海信商城:海信电视、科龙空调、容声冰箱官方专卖
2017/02/07 全球购物
应届护士求职信范文
2014/01/26 职场文书
人事科岗位职责范本
2014/03/02 职场文书
优秀广告词大全
2014/03/19 职场文书
优秀党务工作者事迹材料
2014/05/07 职场文书
义务教育学校标准化建设汇报材料
2014/08/16 职场文书
科级干部群众路线教育实践活动个人对照检查材料
2014/09/19 职场文书
2014年党员整改措施范文
2014/09/21 职场文书
村主任个人对照检查材料
2014/10/01 职场文书
2016寒假假期总结
2015/10/10 职场文书