一、多进程的消息队列

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

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

  操作系统提供了很多机制来实现进程中的通信,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. JAVA中高访问量高并发的问题怎么解决?

    尽量使用缓存,包括用户缓存,信息缓存等,多花点内存来做缓存,可以大量减少与数据库的交互,提高性能. 用jprofiler等工具找出性能瓶颈,减少额外的开销. 优化数据库查询语句,减少直接使用hiber ...

  2. 第一章 介绍Django

    Django是一个网络开发框架,有了这个框架,能是网站开发更高效有趣,能轻松的创建和维护高质量的网站应用. 这一本书的目的是使读者成为一个Django的专家.主要着重两点.第一,深入的解释Django ...

  3. BZOJ1396:识别子串(SAM)

    Description Input 一行,一个由小写字母组成的字符串S,长度不超过10^5 Output L行,每行一个整数,第i行的数据表示关于S的第i个元素的最短识别子串有多长. Sample I ...

  4. PHP-------文件上传的实例

    文件上传的实例 一.上传头像 在注册时,要求用户上传头像,登陆主页面,显示用户信息时,头像也要显示出来. 例子: 注册页面: 图片存数据库时是text类型. <title>无标题文档< ...

  5. EasyUI使用之鼠标双击事件

    easyui鼠标双击事件,使用 onDblClickRow(index, row) 事件,在用户双击一行的时候触发,参数包括: index:点击的行的索引值,该索引值从0开始. row:对应于点击行的 ...

  6. SpringMVC关于请求参数乱码问题

    String names =request.getParameter("name") request主要接收的参数是form提交 form提交有的时候会伴随着乱码,该乱码的格式为I ...

  7. Python入门基础:代码的编码风格

    每种语言都有自己的编码风格,对于Python这种比较注重于空格的影响的代码而言,其风格也是相当重要的. 主要包括以下几点: 1:使用 4 空格缩进,而非 TAB  .在小缩进(可以嵌套更深)和大缩进( ...

  8. Code First 二 DataAnnotation 数据注解

    Code-First中配置域类 我们在前一节学习了默认的代码优先约定.Code-First使用默认约定从您的域类构建概念模型.Code-First利用称为约定而不是配置的编程模式.这意味着您可以通过配 ...

  9. iOS之改变UIAlertViewController字体的颜色

    NSString *message = @"请确认信息是否正确?"; NSString *title = @"提示"; UIAlertController *a ...

  10. 竞赛题解 - NOIP2018 赛道修建

    \(\mathcal {NOIP2018}\) 赛道修建 - 竞赛题解 额--考试的时候大概猜到正解,但是时间不够了,不敢写,就写了骗分QwQ 现在把坑填好了~ 题目 (Copy from 洛谷) 题 ...