进程间通信-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. 判断真实ip

            #region 获取真实ip        /// <summary>        /// 获取真实ip        /// </summary>      ...

  2. vscode中使用Experimental Decorators报错

    在vscode中使用es7的新语法decorator会报错,如图: 这是错误来自与vscode的JS support,只要在项目根目录下创建一个jsconfig.json文件,添加如下内容: { &q ...

  3. Oracle学习操作(3)

    一.if条件语句 set serverout on; ; v ):='world'; begin dbms_output.put_line('hello'||n||v); end; / hello1w ...

  4. html_常用技巧总结

    =============  博客大全: 脚本之家:http://www.jb51.net/list/list_233_104.htm 红黑联盟: http://www.2cto.com/kf/yid ...

  5. java如何写自己的native方法实现调用本地的c++库?

    等待编辑 1:首先可以找一本jni    java native interface相关的书籍来看.

  6. 模拟估算器:scikit-learn Estimator

    转载:https://www.toutiao.com/i6606193174010397187/ 当一个数据科学项目刚刚开始时,关键是要尽可能快地走向一个最小可行的产品(MVP).这个MVP将包含最终 ...

  7. 自己写的jQuery放大镜插件效果(一)(采用一张大图和一张小图片的思路)

    这个思路的方法会带来一个小问题,就是当鼠标放到小图上去时,会开始加载大图片,网速不佳的时候,会出现加载慢的情况.但是放大的效果和你所给出的大图片的清晰度是一样的. 先看效果图: html代码: < ...

  8. OpenGL chapter2

    opengl: 图形硬件的一种软件接口:最大的优点:它的速度快于光线追踪器或软件渲染引擎. GLUT: AUX是OpenGL辅助函数库. 数据类型: GLboolean 位宽:1 GLbyte 8 G ...

  9. Node.js 介绍及安装

    Node.js是一个Javascript运行环境(runtime environment),发布于2009年5月,由Ryan Dahl开发,实质是对Chrome V8引擎进行了封装.本文详细介绍了No ...

  10. HTML5进阶

    内容: 1.geolocation元素 2.video元素和audio元素 3.localStorage 4.WebWorker 5.WebSQL.IndexedDB 6.文件操作.文件拖拽新概念 7 ...