进程间通信-Queue

Process之间有时需要通信,操作系统提供了很多机制来实现进程间的通信。

1. Queue的使用

可以使用multiprocessing模块的Queue实现多进程之间的数据传递,Queue本身是一个消息列队程序,首先用一个小实例来演示一下Queue的工作原理:

#coding=utf-8
from multiprocessing import Queue
q=Queue(3) #初始化一个Queue对象,最多可接收三条put消息
q.put("消息1")
q.put("消息2")
print(q.full()) #False
q.put("消息3")
print(q.full()) #True #因为消息列队已满下面的try都会抛出异常,第一个try会等待2秒后再抛出异常,第二个Try会立刻抛出异常
try:
q.put("消息4",True,2)
except:
print("消息列队已满,现有消息数量:%s"%q.qsize()) 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())

  

运行结果:


False
True
消息列队已满,现有消息数量:3
消息列队已满,现有消息数量:3
消息1
消息2
消息3

说明

初始化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);

2. Queue实例

我们以Queue为例,在父进程中创建两个子进程,一个往Queue里写数据,一个从Queue里读数据:

from multiprocessing import Process, Queue
import os, time, 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()
# pr进程里是死循环,无法等待其结束,只能强行终止:
print ''
print '所有数据都写入并且读完'

  

运行结果:

3. 进程池中的Queue

如果要使用Pool创建进程,就需要使用multiprocessing.Manager()中的Queue(),而不是multiprocessing.Queue(),否则会得到一条如下的错误信息:

RuntimeError: Queue objects should only be shared between processes through inheritance.

下面的实例演示了进程池中的进程如何通信:

#coding=utf-8

#修改import中的Queue为Manager
from multiprocessing import Manager,Pool
import os,time,random def reader(q):
print("reader启动(%s),父进程为(%s)"%(os.getpid(),os.getppid()))
for i in range(q.qsize()):
print("reader从Queue获取到消息:%s"%q.get(True)) def writer(q):
print("writer启动(%s),父进程为(%s)"%(os.getpid(),os.getppid()))
for i in "dongGe":
q.put(i) if __name__=="__main__":
print("(%s) start"%os.getpid())
q=Manager().Queue() #使用Manager中的Queue来初始化
po=Pool()
#使用阻塞模式创建进程,这样就不需要在reader中使用死循环了,可以让writer完全执行完成后,再用reader去读取
po.apply(writer,(q,))
po.apply(reader,(q,))
po.close()
po.join()
print("(%s) End"%os.getpid())

  

运行结果:


(21156) start
writer启动(21162),父进程为(21156)
reader启动(21162),父进程为(21156)
reader从Queue获取到消息:d
reader从Queue获取到消息:o
reader从Queue获取到消息:n
reader从Queue获取到消息:g
reader从Queue获取到消息:G
reader从Queue获取到消息:e
(21156) End

进程间通信-Queue的更多相关文章

  1. 多任务fork、multiprocessing、进程池、进程间通信-Queue

    并发:一个处理器同时处理多个任务. 并行:多个处理器或者是多核的处理器同时处理多个不同的任务. fork创建子进程 import os import time #fork出一个子进程,子进程也从这一行 ...

  2. 4 进程间通信Queue [kjuː]

    1.进程间通信-Queue Process之间有时需要通信,操作系统提供了很多机制来实现进程间的通信. 说明 初始化Queue()对象时(例如:q=Queue()),若括号中没有指定最大可接收的消息数 ...

  3. 8.12 day31 进程间通信 Queue队列使用 生产者消费者模型 线程理论 创建及对象属性方法 线程互斥锁 守护线程

    进程补充 进程通信 要想实现进程间通信,可以用管道或者队列 队列比管道更好用(队列自带管道和锁) 管道和队列的共同特点:数据只有一份,取完就没了 无法重复获取用一份数据 队列特点:先进先出 堆栈特点: ...

  4. python并发编程-进程间通信-Queue队列使用-生产者消费者模型-线程理论-创建及对象属性方法-线程互斥锁-守护线程-02

    目录 进程补充 进程通信前言 Queue队列的基本使用 通过Queue队列实现进程间通信(IPC机制) 生产者消费者模型 以做包子买包子为例实现当包子卖完了停止消费行为 线程 什么是线程 为什么要有线 ...

  5. python进程间通信 queue pipe

    python进程间通信 1 python提供了多种进程通信的方式,主要Queue和Pipe这两种方式,Queue用于多个进程间实现通信,Pipe是两个进程的通信 1.1 Queue有两个方法: Put ...

  6. Python进程间通信Queue

    1.Queue使用方法: Queue.qsize():返回当前队列包含的消息数量: Queue.empty():如果队列为空,返回True,反之False : Queue.full():如果队列满了, ...

  7. 线程_进程间通信Queue合集

    # Queue的工作原理 from multiprocessing import Queue q = Queue(3)#初始化一个Queue对象,最多可接收3条put消息 q.put("In ...

  8. Python进程间通信:Queue

    Python进程间通信Queue 1.Queue使用方法: Queue.qsize():返回当前队列包含的消息数量: Queue.empty():如果队列为空,返回True,反之False : Que ...

  9. day10---multiprocess 多进程

    multiprocess Queue  \ Pipe 只是实现进程间数据的传递 Manager 实现了进程间数据的共享,即多个进程可以修改同一份数据   进程模块 multiprocessing #! ...

随机推荐

  1. RK3399 Android 7.1 删除repo后编译报错

    CPU:RK3399 系统:Android 7.1 瑞芯微使用的是 repo 来进行代码管理,但我们需要用 git 来管理,所以就删除了 repo,但是编译就报错,如下:Server is alrea ...

  2. SpringCloud统一配置笔记

    Server端: pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns= ...

  3. 云-AWS-百科:AWS

    ylbtech-云-AWS-百科:AWS Amazon Web Services AWS是亚马逊公司旗下云计算服务平台,为全世界范围内的客户提供云解决方案.AWS面向用户提供包括弹性计算.存储.数据库 ...

  4. Vue引用其他组件,但组件某些部分不需要时的简单处理

    项目开发时,我们会把多个地方重复使用的模块抽象成组件,提供给大家一起使用,但是使用组件的时候偶尔会遇见一些问题,比如说组件里只有某些东西自己并不需要,这个时候我们可以对组件进行简单的修改,而不影响其他 ...

  5. crunch字典生成

    密码破解基本有三种方法:第一种是人工猜解(垃圾桶工程和被动信息收集): 第二种是基于字典暴力破解(主流) 在kali里,是默认自带了字典的,分别放在下面三个文件中:/usr/share/wordlis ...

  6. xgCalendar在ASP.NET中的使用

    1.将wdCalendar文件夹考入项目中 2.在页面中添加引用,见3中head标签中定义 3.配置xgCalendar,两段代码放在一起就是完整的页面 body> <div> &l ...

  7. 【C++11新特性】 - 空间配置allocator类

    原文链接: http://blog.csdn.net/Xiejingfa/article/details/50955295 今天我们来讲讲C++的allocator类. C++提供了new和delet ...

  8. PHP 算术运算符

    PHP 算术运算符 运算符 名称 描述 实例 结果 x + y 加 x 和 y 的和 2 + 2 4 x - y 减 x 和 y 的差 5 - 2 3 x * y 乘 x 和 y 的积 5 * 2 1 ...

  9. sencha touch 小米3无法点击问题 修复

    修改源码文件夹下event/publisher/Dom.js中的attachListener方法,代码如下 attachListener: function(eventName, doc) { if ...

  10. win10 停留在启动画面

    这是由于部分电脑的主板不支持快速启动造成的,所以把快速启动功能关闭掉即可.具体操作步骤如下:控制面板--硬件和声音--电源选项--选择电源按钮的功能--选择“更改当前不可用的设置”,然后把“启用快速启 ...