一、多进程的消息队列

  “消息队列”是在消息的传输过程中保存消息的容器

  消息队列最经典的用法就是消费者和生成者之间通过消息管道来传递消息,消费者和生成者是不通的进程。生产者往管道中写消息,消费者从管道中读消息。

  操作系统提供了很多机制来实现进程中的通信,multiprocessing模块就提供了queue和pipe两种方法来实现

  使用multiprocessing里面的queue来实现消息队列,代码如下:

from multiprocessing import Process
from multiprocessing import Queue def write(q):
for i in ["a","b","c","d"]:
q.put(i)
print ("put {0} to queue".format(i)) def read(q):
while 1:
result = q.get()
print ("get {0} from queue".format(result)) def main():
q = Queue()
pw = Process(target=write,args=(q,))
pr = Process(target=read,args=(q,))
pw.start()
pr.start()
pw.join()
pr.terminate() if __name__ == "__main__":
main()

结果:

put a to queue
put b to queue
put c to queue
put d to queue
get a from queue
get b from queue
get c from queue
get d from queue

  通过multiprocessing里面的pipe来实现消息队列。pipe方法返回(conn1,conn2)代表一个管道的两个端。pipe方法有duplex参数,如果duplex参数为true(默认值),那么管道是全双工模式,也就是说conn1和conn2均可收发。duplex为false,conn1只负责接受消息,conn2只负责发送消息。

  send和recv方法分别是发送和接收消息的方法,close方法表示关闭管道。当消息接收结束以后,关闭管道。实例代码如下:

from multiprocessing import Process,Pipe

import time

def proc1(pipe):
for i in xrange(1,10):
pipe.send(i)
print ("send {0} to pipe".format(i))
time.sleep(1)
def proc2(pipe):
n = 9
while n>0:
result = pipe.recv()
print ("recv {0} from pipe".format(result))
n -= 1 def main():
pipe = Pipe(duplex=False)
print (type(pipe))
p1 = Process(target = proc1,args=(pipe[1],))
p2 = Process(target= proc2,args=(pipe[0],))
p1.start()
p2.start()
p1.join()
p2.join()
pipe[0].close()
pipe[1].close() if __name__ == "__main__":
main()

结果:

<type 'tuple'>
send 1 to pipe
recv 1 from pipe
send 2 to pipe
recv 2 from pipe
send 3 to pipe
recv 3 from pipe
send 4 to piperecv 4 from pipe

send 5 to pipe
recv 5 from pipe
send 6 to pipe
recv 6 from pipe
send 7 to pipe
recv 7 from pipe
send 8 to pipe
recv 8 from pipe
send 9 to pipe
recv 9 from pipe

二、Queue模块

  Python提供了Queue模块来专门实现消息队列。Queue对象实现一个FIFO队列(其他的还有lifo、priority队列)。Queue只有maxsize一个构造参数,用来指定队列容量,指定为0的时候代表容量无限。主要有以下成员函数:

  Queue.qsize:返回消息队列的当前空间。返回值不一定可靠

  Queue.empty():判断消息队列是否为空,返回True或False。同样不可靠。

  Queue.full():类似上边,判断消息队列是否满

  Queue.put(item,block=True,timeout=None):往消息队列中存放消息。block可以控制是否阻塞,timeout指定阻塞时候的等待时间。如果不阻塞或者超时,会引起一个full exception

  Queue.put_nowait(item):相当于put(itme,False)

  Queue.get(block = True,timeout = None):获取一个消息,其他同put

  Queue.task_done():接受消息的线程通过调用这个函数来说明消息对应的任务已完成

  Queue.join():实际上意味着等队列为空,再执行别的操作

程序实例如下:

from Queue import Queue
from threading import Thread import time class Proceduer(Thread):
def __init__(self,queue):
super(Proceduer,self).__init__()
self.queue = queue def run(self):
try:
for i in xrange(1,10):
print ("put data is : {0} to queue".format(i))
self.queue.put(i)
except Exception as e:
print ("put data error")
raise e class Consumer_odd(Thread):
def __init__(self,queue):
super(Consumer_odd,self).__init__()
self.queue = queue
def run(self):
try:
while not self.queue.empty:
number = self.queue.get()
if number % 2 != 0:
print ("get {0} from queue ODD,thread name is :{1}".format(number,self.getName()))
else:
self.queue.put(number)
time.sleep(1)
except Exception as e :
raise e class Consumer_even(Thread):
def __init__(self,queue):
super(Consumer_even,self).__init__()
self.queue = queue
def run(self):
try:
while not self.queue.empty:
number = self.queue.get()
if number % 2 == 0:
print ("get {0} from queue Even,thread name is :{1}".format(number,self.getName()))
else:
self.queue.put(number)
time.sleep(1)
except Exception as e :
raise e def main():
queue = Queue()
p = Proceduer(queue = queue)
p.start()
p.join()
time.sleep(1)
c1 = Consumer_odd(queue=queue)
c2 = Consumer_even(queue=queue)
c1.start()
c2.start()
c1.join()
c2.join()
print ("All threads is terminate!") if __name__ == '__main__':
main()

结果:

put data is : 2 to queue
put data is : 3 to queue
put data is : 4 to queue
put data is : 5 to queue
put data is : 6 to queue
put data is : 7 to queue
put data is : 8 to queue
put data is : 9 to queue
get 1 from queue ODD,thread name is :Thread-2
get 2 from queue Even,thread name is :Thread-3
get 3 from queue ODD,thread name is :Thread-2
 get 4 from queue Even,thread name is :Thread-3
get 5 from queue ODD,thread name is :Thread-2
 get 6 from queue Even,thread name is :Thread-3
get 9 from queue ODD,thread name is :Thread-2
get 8 from queue Even,thread name is :Thread-3
 get 7 from queue ODD,thread name is :Thread-2

python之Queue的更多相关文章

  1. Python中Queue模块及多线程使用

    Python的Queue模块提供一种适用于多线程编程的FIFO实现.它可用于在生产者(producer)和消费者(consumer)之间线程安全(thread-safe)地传递消息或其它数据,因此多个 ...

  2. Python队列queue模块

    Python中queue模块常用来处理队列相关问题 队列常用于生产者消费者模型,主要功能为提高效率和程序解耦 1. queue模块的基本使用和相关说明 # -*- coding:utf-8 -*- # ...

  3. python队列Queue

    Queue Queue是python标准库中的线程安全的队列(FIFO)实现,提供了一个适用于多线程编程的先进先出的数据结构,即队列,用来在生产者和消费者线程之间的信息传递 基本FIFO队列 clas ...

  4. Python之Queue模块

    Queue 1.创建一个“队列”对象 >>> import Queue >>> queue = Queue.Queue(maxsize=100) >>& ...

  5. 后台程序处理(二) python threading - queue 模块使用

    由于协程没办法完成(一)中所说的任务模式 接下来就尝试一下使用线程和队列来实现一下这个功能 在实现之前,我们先明确一个问题--python的线程是伪并发的.同一时间只能有一个线程在运行.具体怎样的运作 ...

  6. python socket非阻塞及python队列Queue

    一. python非阻塞编程的settimeout与setblocking+select 原文:www.th7.cn/Program/Python/201406/214922.shtml 侧面认证Py ...

  7. Python|队列Queue

    一 前言 本文算是一次队列的学习笔记,Queue 模块实现了三种类型的队列,它们的区别仅仅是队列中元素被取回的顺序.在 FIFO 队列中,先添加的任务先取回.在 LIFO 队列中,最近被添加的元素先取 ...

  8. python基础 — Queue 队列

    queue介绍 queue是python中的标准库,俗称队列. 在python中,多个线程之间的数据是共享的,多个线程进行数据交换的时候,不能够保证数据的安全性和一致性,所以当多个线程需要进行数据交换 ...

  9. python进程间通信 queue pipe

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

随机推荐

  1. was缓存以致web.xml更改无效

    was缓存导致web.xml更改无效 在项目中经常遇见这样的问题:修改应用的配置文件web.xml后,无论重启应用还是重启WebSphere服务器,都不能重新加载web.xml,导致修改的内容无效. ...

  2. 洛谷 P4321 【随机漫游】

    题目大意 给出\(n(n\leq 18)\)个点的无向连通图,\(m(m\leq 10^5)\)次询问.每次询问给出一个点集和一个起点\(s\),询问从\(s\)出发,经过这个点集中的每一个点至少一次 ...

  3. MVVM的核心:双向绑定

    MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致. 唯一的区别是,它采用双向绑定(data-binding):View的变动,自动反映在 ViewMod ...

  4. 在win7中通过手机投放媒体

    依次展开>>> 设置项 开启服务项: 和   在更给网络属性为 打开wmplayer开启两个允许 在手机端无线投屏选择设备即可

  5. Mac系统下配置JAVA Maven Ant 环境变量

    Mac 启动加载文件位置(可设置环境变量) ------------------------------------------------------- (1)首先要知道你使用的Mac OS X是什 ...

  6. npm run build 打包后,如何运行在本地查看效果

    目前,使用vue-cli脚手架写了一个前端项目,之前一直是使用npm run dev 在8080端口上进行本地调试.项目已经进行一半了,今天有时间突然想使用npm run build进行上线打包,试试 ...

  7. CentOS 安装postgresql

    CentOS 安装postgresql   添加postgresql官网安装源 在/etc/yum.repos.d目录下新建pgdg-10-centos.repo 文件 [pgdg10] name=P ...

  8. Vertical-Align你应该知道的一切

    好,我们聊聊vertical-align.这个属性主要目的用于将相邻的文本与元素对齐.而实际上,verticle-algin可以在不同上下文中灵活地对齐元素,以及进行细粒度的控制,不必知道元素的大小. ...

  9. Process.waitFor()导致主线程堵塞问题

    今日开发的时候使用jdk自带的运行时变量 RunTime.getRunTime() 去执行bash命令.因为该bash操作耗时比较长,所以使用了Process.waitFor()去等待子线程运行结束. ...

  10. Java反射机制--是什么,为什么,怎么用。

    往往当我们面对一项新的知识时,我们往往需要知道三个方面,它是什么,它能做什么,它比原有知识强在哪里,我们该怎么使用它.当你能够解决这些问题时,便意味着你已经对这项知识入门了. 一.是什么 Java R ...