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通过urllib2爬网页上种子下载示例
Feb 24 Python
Python的GUI框架PySide的安装配置教程
Feb 16 Python
Numpy array数据的增、删、改、查实例
Jun 04 Python
对Python信号处理模块signal详解
Jan 09 Python
python使用requests.session模拟登录
Aug 09 Python
win7下 python3.6 安装opencv 和 opencv-contrib-python解决 cv2.xfeatures2d.SIFT_create() 的问题
Oct 24 Python
python ImageDraw类实现几何图形的绘制与文字的绘制
Feb 26 Python
python 画图 图例自由定义方式
Apr 17 Python
python 引用传递和值传递详解(实参,形参)
Jun 05 Python
在python中使用pyspark读写Hive数据操作
Jun 06 Python
如何用python免费看美剧
Aug 11 Python
Python Pandas知识点之缺失值处理详解
May 11 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关于array_multisort多维数组排序的使用说明
2011/01/04 PHP
php实现httpclient类示例
2014/04/08 PHP
php中最简单的字符串匹配算法
2014/12/16 PHP
php抛出异常与捕捉特定类型的异常详解
2016/10/26 PHP
php微信开发之谷歌测距
2018/06/14 PHP
php设计模式之观察者模式实例详解【星际争霸游戏案例】
2020/03/30 PHP
Js 订制自己的AlertBox(信息提示框)
2009/01/09 Javascript
一个简单的Ext.XTemplate的实例代码
2012/03/18 Javascript
JS 调试中常见的报错问题解决方法
2017/05/20 Javascript
form表单数据封装成json格式并提交给服务器的实现方法
2017/12/14 Javascript
jQuery实现弹窗下底部页面禁止滑动效果
2017/12/19 jQuery
基于vue 动态加载图片src的解决方法
2018/02/05 Javascript
Vue 去除路径中的#号
2018/04/19 Javascript
解决layui前端框架 form表单,table表等内置控件不显示的问题
2018/08/19 Javascript
React Router V4使用指南(精讲)
2018/09/17 Javascript
详解Vue中使用Axios拦截器
2019/04/22 Javascript
vue项目中全局引入1个.scss文件的问题解决
2019/08/01 Javascript
jQuery HTML获取内容和属性操作实例分析
2020/05/20 jQuery
python使用锁访问共享变量实例解析
2018/02/08 Python
Python3实现购物车功能
2018/04/18 Python
33个Python爬虫项目实战(推荐)
2019/07/08 Python
Django项目中使用JWT的实现代码
2019/11/04 Python
OpenCV+python实现实时目标检测功能
2020/06/24 Python
解决Ubuntu18中的pycharm不能调用tensorflow-gpu的问题
2020/09/17 Python
python IP地址转整数
2020/11/20 Python
使用CSS3在触屏上为按钮实现激活效果
2013/09/27 HTML / CSS
香港中原电器网上商店:Chung Yuen
2019/06/26 全球购物
写给老师的表扬信
2014/01/21 职场文书
中学自我评价
2014/01/31 职场文书
工程建设实施方案
2014/03/14 职场文书
8和9的加减法教学反思
2014/05/01 职场文书
公司离职证明标准范本
2014/10/05 职场文书
家庭贫困证明
2015/06/16 职场文书
师范生小学见习总结
2015/06/23 职场文书
高考升学宴主持词
2019/06/21 职场文书
TypeScript实用技巧 Nominal Typing名义类型详解
2022/09/23 Javascript