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实现自动登录百度空间的方法
Jun 10 Python
R vs. Python 数据分析中谁与争锋?
Oct 18 Python
Python global全局变量函数详解
Sep 18 Python
python利用selenium进行浏览器爬虫
Apr 25 Python
Django框架之DRF 基于mixins来封装的视图详解
Jul 23 Python
详解pandas DataFrame的查询方法(loc,iloc,at,iat,ix的用法和区别)
Aug 02 Python
Python 中list ,set,dict的大规模查找效率对比详解
Oct 11 Python
利用setuptools打包python程序的方法步骤
Jan 18 Python
python with (as)语句实例详解
Feb 04 Python
pytorch实现从本地加载 .pth 格式模型
Feb 14 Python
一篇文章搞懂python的转义字符及用法
Sep 03 Python
Python保存并浏览用户的历史记录
Apr 29 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初学者常见问题集合 修正版(21问答)
2010/03/23 PHP
解析php中memcache的应用
2013/06/18 PHP
超强多功能php绿色集成环境详解
2017/01/25 PHP
Javascript技巧之不要用for in语句对数组进行遍历
2010/10/20 Javascript
iphone safari不支持position fixed的解决方法
2012/05/04 Javascript
浅谈String.valueOf()方法的使用
2016/06/06 Javascript
webpack2.0搭建前端项目的教程详解
2017/04/05 Javascript
Node.js 使用命令行工具检查更新
2017/06/08 Javascript
AngularJS解决ng-if中的ng-model值无效的问题
2017/06/21 Javascript
详解vue-cli与webpack结合如何处理静态资源
2017/09/19 Javascript
详解koa2学习中使用 async 、await、promise解决异步的问题
2018/11/13 Javascript
微信小程序使用map组件实现解析经纬度功能示例
2019/01/22 Javascript
微信小程序实现传递多个参数与事件处理
2019/08/12 Javascript
Vue程序化的事件监听器(实例方案详解)
2020/01/07 Javascript
微信小程序纯文本实现@功能
2020/04/08 Javascript
[01:07:17]EG vs Optic Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
Python 文件重命名工具代码
2009/07/26 Python
在Python中用has_key()方法查找键是否存在的教程
2015/05/21 Python
vue.js实现输入框输入值内容实时响应变化示例
2018/07/07 Python
Python定时任务sched模块用法示例
2018/07/16 Python
pytorch-神经网络拟合曲线实例
2020/01/15 Python
tensorflow 利用expand_dims和squeeze扩展和压缩tensor维度方式
2020/02/07 Python
解决Tensorboard可视化错误:不显示数据 No scalar data was found
2020/02/15 Python
Python django框架 web端视频加密的实例详解
2020/11/20 Python
迪士尼英国官方商店:shopDisney UK
2019/09/21 全球购物
简历的自荐信
2013/12/19 职场文书
高三体育教学反思
2014/01/29 职场文书
《手指教学》反思
2014/02/14 职场文书
单位租房协议书样本
2014/10/30 职场文书
幼儿园大班毕业评语
2014/12/31 职场文书
合作意向协议书
2015/01/29 职场文书
刑事上诉状(无罪)
2015/05/23 职场文书
2016元旦主持人经典开场白台词
2015/12/03 职场文书
2016入党心得体会范文
2016/01/06 职场文书
Pandas||过滤缺失数据||pd.dropna()函数的用法说明
2021/05/14 Python
详解Nginx 被动检查服务器的存活状态
2021/10/16 Servers