一、多进程的消息队列

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

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

  操作系统提供了很多机制来实现进程中的通信,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. Hadoop-2.2.0中文文档—— Common - 超级用户模拟别的用户

    简单介绍 此文档描写叙述了一个超级用户怎样在安全的方式下以还有一用户的名义提交作业或訪问hdfs. Use Case 下一部分描写叙述的的代码演示样例对此用户用例是可用的. 一个username为's ...

  2. Sublime Text 3中关闭记住上次打开的文件

    使用UltraEdit的时候,每次安装后就得修改一堆配置,其中一项便是关闭“打开上一次未关闭的文件”,Sublime Text 2也有这么一个默认的功能,在实际使用中,这种方式确实可以较快速的访问文件 ...

  3. Anaconda安装与常用命令及方法(深度学习入门1)

    Anaconda是一个软件发行版,它附带了 conda.Python 和 150 多个科学包及其依赖项. 安装Anaconda Anaconda分为Linux.Windows.Mac等版本,去 htt ...

  4. 【luogu P4017 最大食物链计数】 题解

    题目链接:https://www.luogu.org/problemnew/show/P4017 DAG + DP #include <queue> #include <cstdio ...

  5. Google Guava -缓存cache简单使用

    package guavacache; import java.util.concurrent.ExecutionException; import java.util.concurrent.Time ...

  6. Java中,如何跳出当前的多重嵌套循环

    在最外层循环前加一个标记如A,然后用break A;可以跳出多重循环.(Java中支持带标签的break和continue语句)

  7. 一点一点看JDK源码(五)java.util.ArrayList 后篇之Spliterator多线程遍历

    一点一点看JDK源码(五)java.util.ArrayList 后篇之Spliterator多线程遍历 liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看J ...

  8. 阿里云修改主机名(以centOS为例)

    需要更改配置文件生效,修/etc/sysconfig/network里的 HOSTNAME=主机名(可自定义),重启生效. 如何修改? 1.[root@aliyunbaike ~]# cd /etc/ ...

  9. 【oracle使用笔记1】SQL报的常见错误

    项目中使用最多的就是oracle数据库了,在实际的开发中书写SQL时遇到过许多错误,趁着现在不太忙,把之前遇到的总结一下,以后遇到的会持续更新总结. 1. ORA-00001:违反唯一约束条件 [原因 ...

  10. Tomcat性能监控

    Tomcat性能监控工具很多,这里介绍两种1.JMeter 2.probe,使用这两种工具都需要在tomcat的安装目录/conf/tomcat-users.xml添加 <tomcat-user ...