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解析ini配置文件实例
Aug 30 Python
python计算N天之后日期的方法
Mar 31 Python
不可错过的十本Python好书
Jul 06 Python
利用python如何处理百万条数据(适用java新手)
Jun 06 Python
Python自动发送邮件的方法实例总结
Dec 08 Python
python 提取tuple类型值中json格式的key值方法
Dec 31 Python
python交互模式下输入换行/输入多行命令的方法
Jul 02 Python
matplotlib命令与格式之tick坐标轴日期格式(设置日期主副刻度)
Aug 06 Python
使用 Python 在京东上抢口罩的思路详解
Feb 27 Python
解决pycharm不能自动补全第三方库的函数和属性问题
Mar 12 Python
使用tensorflow根据输入更改tensor shape
Jun 23 Python
python可视化 matplotlib画图使用colorbar工具自定义颜色
Dec 07 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
escape unescape的php下的实现方法
2007/04/27 PHP
微信公众平台开发之配置与请求
2015/08/26 PHP
php限制文件下载速度的代码
2015/10/20 PHP
Laravel中使用FormRequest进行表单验证方法及问题汇总
2016/06/19 PHP
JMenuTab简单使用说明
2008/03/13 Javascript
lyhucSelect基于Jquery的Select数据联动插件
2011/03/29 Javascript
js 判断控件获得焦点的示例代码
2014/03/04 Javascript
javascript的函数作用域
2014/11/12 Javascript
javascript实用方法总结
2015/02/06 Javascript
jquery validate.js表单验证入门实例(附源码)
2015/11/10 Javascript
javascript动态添加checkbox复选框的方法
2015/12/23 Javascript
无需 Flash 使用 jQuery 复制文字到剪贴板
2016/04/26 Javascript
JavaScript之DOM插入更新删除_动力节点Java学院整理
2017/07/03 Javascript
详解react-native-fs插件的使用以及遇到的坑
2017/09/12 Javascript
Vue代码分割懒加载的实现方法
2017/11/23 Javascript
微信小程序使用picker实现时间和日期选择框功能【附源码下载】
2017/12/11 Javascript
vue如何引入sass全局变量
2018/06/28 Javascript
layer的prompt弹出框,点击回车,触发确定事件的方法
2019/09/06 Javascript
JavaScript仿京东秒杀倒计时
2020/03/17 Javascript
vue实现一个矩形标记区域(rectangle marker)的方法
2020/10/28 Javascript
Python的lambda匿名函数的简单介绍
2013/04/25 Python
Django视图之ORM数据库查询操作API的实例
2017/10/27 Python
浅谈python 导入模块和解决文件句柄找不到问题
2018/12/15 Python
Python requests模块实例用法
2019/02/11 Python
Python实现的爬取豆瓣电影信息功能案例
2019/09/15 Python
python编写计算器功能
2019/10/25 Python
Python使用py2neo操作图数据库neo4j的方法详解
2020/01/13 Python
Pandas之read_csv()读取文件跳过报错行的解决
2020/04/21 Python
python异常处理之try finally不报错的原因
2020/05/18 Python
Python关于拓扑排序知识点讲解
2021/01/04 Python
英国马莎百货印度官网:Marks & Spencer印度
2020/10/08 全球购物
应届毕业生个人求职自荐信
2014/01/06 职场文书
个人担保书范文
2014/05/20 职场文书
党员群众路线个人整改措施思想汇报
2014/10/12 职场文书
挂职锻炼个人总结
2015/03/05 职场文书
2015年工商所工作总结
2015/05/21 职场文书