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 相关文章推荐
linux系统使用python监控apache服务器进程脚本分享
Jan 15 Python
django自定义Field实现一个字段存储以逗号分隔的字符串
Apr 27 Python
Python xlrd读取excel日期类型的2种方法
Apr 28 Python
浅谈Django REST Framework限速
Dec 12 Python
python中使用PIL制作并验证图片验证码
Mar 15 Python
python list删除元素时要注意的坑点分享
Apr 18 Python
pandas DataFrame的修改方法(值、列、索引)
Aug 02 Python
利用python实现短信和电话提醒功能的例子
Aug 08 Python
python创建ArcGIS shape文件的实现
Dec 06 Python
python 回溯法模板详解
Feb 26 Python
Python如何定义有默认参数的函数
Aug 10 Python
python Cartopy的基础使用详解
Nov 01 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处理SQL脚本文件导入到MySQL的代码实例
2014/03/17 PHP
腾讯CMEM的PHP扩展编译安装方法
2015/09/25 PHP
WordPres对前端页面调试时的两个PHP函数使用小技巧
2015/12/22 PHP
php版微信发红包接口用法示例
2016/09/23 PHP
PHP中register_shutdown_function函数的基础介绍与用法详解
2017/11/28 PHP
PHP实现的字符串匹配算法示例【sunday算法】
2017/12/19 PHP
火狐下table中创建form导致两个table之间出现空白
2013/09/02 Javascript
js实现浏览器窗口大小被改变时触发事件的方法
2015/02/02 Javascript
jQuery插件Flexslider实现图片轮播、图文结合滑动切换效果
2020/04/16 Javascript
AngularJS中transclude用法详解
2016/11/03 Javascript
JS判断Android、iOS或浏览器的多种方法(四种方法)
2017/06/29 Javascript
JS实现字符串中去除指定子字符串方法分析
2018/05/17 Javascript
vue+ElementUI 关闭对话框清空验证,清除form表单的操作
2020/08/06 Javascript
ES6中的Javascript解构的实现
2020/10/30 Javascript
jQuery实现鼠标拖动图片功能
2021/03/04 jQuery
[01:14]2014DOTA2展望TI 剑指西雅图newbee战队专访
2014/06/30 DOTA
写了个监控nginx进程的Python脚本
2012/05/10 Python
学习python的几条建议分享
2013/02/10 Python
python图像处理之反色实现方法
2015/05/30 Python
python调用fortran模块
2016/04/08 Python
python通过getopt模块如何获取执行的命令参数详解
2017/12/29 Python
对python .txt文件读取及数据处理方法总结
2018/04/23 Python
Python3内置模块之base64编解码方法详解
2019/07/13 Python
python xlwt如何设置单元格的自定义背景颜色
2019/09/03 Python
Python3的socket使用方法详解
2020/02/18 Python
Python3自定义json逐层解析器代码
2020/05/11 Python
django 获取字段最大值,最新的记录操作
2020/08/09 Python
python基于爬虫+django,打造个性化API接口
2021/01/21 Python
通用的Django注册功能模块实现方法
2021/02/05 Python
Html5定位终极解决方案
2020/02/05 HTML / CSS
注塑工厂厂长岗位职责
2013/12/02 职场文书
治超工作实施方案
2014/05/04 职场文书
专科应届毕业生求职信
2014/06/04 职场文书
2015年医德医风工作总结
2015/04/02 职场文书
vue实现水波涟漪效果的点击反馈指令
2021/05/31 Vue.js
div与span之间的区别与使用介绍
2021/12/06 HTML / CSS