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实现Linux中的du命令
Jun 12 Python
Python 多进程并发操作中进程池Pool的实例
Nov 01 Python
Python排序搜索基本算法之堆排序实例详解
Dec 08 Python
Python面向对象之继承和多态用法分析
Jun 08 Python
python全栈知识点总结
Jul 01 Python
Python 绘制酷炫的三维图步骤详解
Jul 12 Python
如何实现Django Rest framework版本控制
Jul 25 Python
python类的实例化问题解决
Aug 31 Python
详解numpy矩阵的创建与数据类型
Oct 18 Python
python实现将两个文件夹合并至另一个文件夹(制作数据集)
Apr 03 Python
详解pandas绘制矩阵散点图(scatter_matrix)的方法
Apr 23 Python
Python安装Bs4的多种方法
Nov 28 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
手把手教你打印出PDF(关于fpdf的简单应用)
2013/06/25 PHP
php cli配置文件问题分析
2015/10/15 PHP
JSON两种结构之对象和数组的理解
2016/07/19 PHP
PHP数据对象PDO操作技巧小结
2016/09/27 PHP
JScript中的undefined和"undefined"的区别
2007/03/08 Javascript
JavaScript中的闭包原理分析
2010/03/08 Javascript
Jquery拖拽并简单保存的实现代码
2010/11/28 Javascript
JavaScript中:表达式和语句的区别[译]
2012/09/17 Javascript
jQuery:节点(插入,复制,替换,删除)操作
2013/03/04 Javascript
js中文逗号转英文实现
2014/02/11 Javascript
Jquery对数组的操作技巧整理
2014/03/25 Javascript
用简洁的jQuery方法toggleClass实现隔行换色
2014/10/22 Javascript
3个可以改善用户体验的AngularJS指令介绍
2015/06/18 Javascript
探究JavaScript函数式编程的乐趣
2015/12/14 Javascript
jQuery form插件之ajaxForm()和ajaxSubmit()的可选参数项对象
2016/01/23 Javascript
BootStrap fileinput.js文件上传组件实例代码
2017/02/20 Javascript
Angular.js实现多个checkbox只能选择一个的方法示例
2017/02/24 Javascript
Vue.js实例方法之生命周期详解
2017/07/03 Javascript
详解vue渲染函数render的使用
2017/12/12 Javascript
详解Vue.js自定义tipOnce指令用法实例
2018/12/19 Javascript
layui 上传文件_批量导入数据UI的方法
2019/09/23 Javascript
vue 实现走马灯效果
2019/10/28 Javascript
angular8和ngrx8结合使用的步骤介绍
2019/12/01 Javascript
JavaScript异步操作的几种常见处理方法实例总结
2020/05/11 Javascript
Python找出微信上删除你好友的人脚本写法
2018/11/01 Python
使用python实现离散时间傅里叶变换的方法
2019/09/02 Python
pyecharts绘制中国2020肺炎疫情地图的实例代码
2020/02/12 Python
HTML5 Canvas 实现K线图的示例代码
2019/12/23 HTML / CSS
英国最大的在线运动补充剂商店:Discount Supplements
2017/06/03 全球购物
美国购买当代和现代家具网站:MODTEMPO
2018/07/20 全球购物
大学生创业策划书
2014/02/02 职场文书
2014年秋季新学期寄语
2014/08/02 职场文书
2014年初级职称工作总结
2014/12/08 职场文书
2014小学语文教学工作总结
2014/12/17 职场文书
2015年国际护士节演讲稿
2015/03/18 职场文书
clear 万能清除浮动(clearfix:after)
2023/05/21 HTML / CSS