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 相关文章推荐
Python3基础之基本数据类型概述
Aug 13 Python
python格式化字符串实例总结
Sep 28 Python
利用Django框架中select_related和prefetch_related函数对数据库查询优化
Apr 01 Python
python获取从命令行输入数字的方法
Apr 29 Python
python实现将元祖转换成数组的方法
May 04 Python
构建Python包的五个简单准则简介
Jun 15 Python
使用python编写监听端
Apr 12 Python
Pycharm设置去除显示的波浪线方法
Oct 28 Python
Python3搭建http服务器的实现代码
Feb 11 Python
Python datetime模块使用方法小结
Jun 18 Python
详解python UDP 编程
Aug 24 Python
Python fileinput模块如何逐行读取多个文件
Oct 05 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
中国第一家无线电行
2021/03/01 无线电
让你的WINDOWS同时支持MYSQL4,MYSQL4.1,MYSQL5X
2006/12/06 PHP
php的chr和ord函数实现字符加减乘除运算实现代码
2011/12/05 PHP
作为程序员必知的16个最佳PHP库
2015/12/09 PHP
thinkPHP模板引擎用法示例
2016/12/08 PHP
Prototype使用指南之enumerable.js
2007/01/10 Javascript
ymPrompt的doHandler方法来实现获取子窗口返回值的方法
2010/06/25 Javascript
8个超棒的学习 jQuery 的网站 推荐收藏
2011/04/02 Javascript
node.js中的console.error方法使用说明
2014/12/10 Javascript
JS扩展方法实例分析
2015/04/15 Javascript
前端微信支付js代码
2016/07/25 Javascript
浅谈angular懒加载的一些坑
2016/08/20 Javascript
浅谈JS的基础类型与引用类型
2016/09/13 Javascript
JS填写银行卡号每隔4位数字加一个空格
2016/12/19 Javascript
jQuery实现表格元素动态创建功能
2017/01/09 Javascript
Vue ElementUI之Form表单验证遇到的问题
2017/08/21 Javascript
vue 中directive功能的简单实现
2018/01/05 Javascript
详解javascript appendChild()的完整功能
2018/08/18 Javascript
微信小程序用户拒绝授权的处理方法详解
2019/09/20 Javascript
微信小程序wx.navigateTo方法里的events参数使用详情及场景
2020/01/07 Javascript
使用 Github Actions 自动部署 Angular 应用到 Github Pages的方法
2020/07/20 Javascript
Python下的twisted框架入门指引
2015/04/15 Python
使用FastCGI部署Python的Django应用的教程
2015/07/22 Python
Python实现公历(阳历)转农历(阴历)的方法示例
2017/08/22 Python
详解Python 协程的详细用法使用和例子
2018/06/15 Python
Python使用pyshp库读取shapefile信息的方法
2018/12/29 Python
python使用tomorrow实现多线程的例子
2019/07/20 Python
详解用python计算阶乘的几种方法
2019/08/14 Python
Python爬虫谷歌Chrome F12抓包过程原理解析
2020/06/04 Python
Pycharm 解决自动格式化冲突的设置操作
2021/01/15 Python
检测浏览器是否支持html5视频的代码
2013/03/28 HTML / CSS
外语专业毕业生自我评价分享
2013/10/05 职场文书
通知的格式范文
2015/04/27 职场文书
期中考试后的感想
2015/08/07 职场文书
python机器学习实现oneR算法(以鸢尾data为例)
2022/03/03 Python
MySql中的json_extract函数处理json字段详情
2022/06/05 MySQL