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 入门教程 简单但比较不错
Nov 29 Python
python操作ie登陆土豆网的方法
May 09 Python
Python之web模板应用
Dec 26 Python
python实现简单http服务器功能
Sep 17 Python
对Python 语音识别框架详解
Dec 24 Python
Python使用Pandas库实现MySQL数据库的读写
Jul 06 Python
Python 的AES加密与解密实现
Jul 09 Python
在python中计算ssim的方法(与Matlab结果一致)
Dec 19 Python
Django 解决distinct无法去除重复数据的问题
May 20 Python
python三引号如何输入
Jul 06 Python
Python 可迭代对象 iterable的具体使用
Aug 07 Python
Python多线程实用方法以及共享变量资源竞争问题
Apr 12 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
preg_match_all使用心得分享
2014/01/31 PHP
ThinkPHP使用心得分享-分页类Page的用法
2014/05/15 PHP
Zend Framework教程之视图组件Zend_View用法详解
2016/03/05 PHP
php记录搜索引擎爬行记录的实现代码
2018/03/02 PHP
为超链接加上disabled后的故事
2010/12/10 Javascript
使用Json比用string返回数据更友好,也更面向对象一些
2011/09/13 Javascript
js三种排序算法分享
2012/08/16 Javascript
jQuery $.data()方法使用注意细节
2012/12/31 Javascript
JS+flash实现chrome和ie浏览器下同时可以复制粘贴
2013/09/22 Javascript
jQuery操作JSON的CRUD用法实例
2015/02/25 Javascript
基于jQuery和CSS3制作数字时钟附源码下载(jquery篇)
2015/11/24 Javascript
jQueryUI中的datepicker使用方法详解
2016/05/25 Javascript
jQuery实现两列等高并自适应高度
2016/12/22 Javascript
vue2.0组件之间传值、通信的多种方式(干货)
2018/02/10 Javascript
使用Vue.js和Flask来构建一个单页的App的示例
2018/03/21 Javascript
快速解决vue在ios端下点击响应延时的问题
2018/08/27 Javascript
Python进程间通信Queue实例解析
2018/01/25 Python
Python中使用pypdf2合并、分割、加密pdf文件的代码详解
2019/05/21 Python
python读取ini配置的类封装代码实例
2020/01/08 Python
基于python实现地址和经纬度转换
2020/05/19 Python
使用Numpy对特征中的异常值进行替换及条件替换方式
2020/06/08 Python
python识别验证码的思路及解决方案
2020/09/13 Python
python 基于UDP协议套接字通信的实现
2021/01/22 Python
浅谈CSS3鼠标移入图片动态提示效果(transform)
2017/11/06 HTML / CSS
详解html5 postMessage解决跨域通信的问题
2018/08/17 HTML / CSS
为什么Runtime.exec(“ls”)没有任何输出?
2014/10/03 面试题
JPA的优势都有哪些
2013/07/04 面试题
党的群众路线教育实践活动心得体会
2014/03/03 职场文书
员工安全生产责任书
2014/07/22 职场文书
幼儿园大班开学寄语
2014/08/02 职场文书
2014国庆节主题活动方案:快乐的国庆节
2014/09/16 职场文书
安全责任书
2015/01/29 职场文书
技术转让协议书
2016/03/19 职场文书
MySQL之PXC集群搭建的方法步骤
2021/05/25 MySQL
TV动画「神渣☆爱豆」公开第一弹主视觉图
2022/03/21 日漫
【海涛教你打DOTA】剑圣第一人称视角解说
2022/04/01 DOTA