一、多进程的消息队列

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

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

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

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

  1. from multiprocessing import Process
  2. from multiprocessing import Queue
  3.  
  4. def write(q):
  5. for i in ["a","b","c","d"]:
  6. q.put(i)
  7. print ("put {0} to queue".format(i))
  8.  
  9. def read(q):
  10. while 1:
  11. result = q.get()
  12. print ("get {0} from queue".format(result))
  13.  
  14. def main():
  15. q = Queue()
  16. pw = Process(target=write,args=(q,))
  17. pr = Process(target=read,args=(q,))
  18. pw.start()
  19. pr.start()
  20. pw.join()
  21. pr.terminate()
  22.  
  23. if __name__ == "__main__":
  24. 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方法表示关闭管道。当消息接收结束以后,关闭管道。实例代码如下:

  1. from multiprocessing import Process,Pipe
  2.  
  3. import time
  4.  
  5. def proc1(pipe):
  6. for i in xrange(1,10):
  7. pipe.send(i)
  8. print ("send {0} to pipe".format(i))
  9. time.sleep(1)
  10. def proc2(pipe):
  11. n = 9
  12. while n>0:
  13. result = pipe.recv()
  14. print ("recv {0} from pipe".format(result))
  15. n -= 1
  16.  
  17. def main():
  18. pipe = Pipe(duplex=False)
  19. print (type(pipe))
  20. p1 = Process(target = proc1,args=(pipe[1],))
  21. p2 = Process(target= proc2,args=(pipe[0],))
  22. p1.start()
  23. p2.start()
  24. p1.join()
  25. p2.join()
  26. pipe[0].close()
  27. pipe[1].close()
  28.  
  29. if __name__ == "__main__":
  30. 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():实际上意味着等队列为空,再执行别的操作

程序实例如下:

  1. from Queue import Queue
  2. from threading import Thread
  3.  
  4. import time
  5.  
  6. class Proceduer(Thread):
  7. def __init__(self,queue):
  8. super(Proceduer,self).__init__()
  9. self.queue = queue
  10.  
  11. def run(self):
  12. try:
  13. for i in xrange(1,10):
  14. print ("put data is : {0} to queue".format(i))
  15. self.queue.put(i)
  16. except Exception as e:
  17. print ("put data error")
  18. raise e
  19.  
  20. class Consumer_odd(Thread):
  21. def __init__(self,queue):
  22. super(Consumer_odd,self).__init__()
  23. self.queue = queue
  24. def run(self):
  25. try:
  26. while not self.queue.empty:
  27. number = self.queue.get()
  28. if number % 2 != 0:
  29. print ("get {0} from queue ODD,thread name is :{1}".format(number,self.getName()))
  30. else:
  31. self.queue.put(number)
  32. time.sleep(1)
  33. except Exception as e :
  34. raise e
  35.  
  36. class Consumer_even(Thread):
  37. def __init__(self,queue):
  38. super(Consumer_even,self).__init__()
  39. self.queue = queue
  40. def run(self):
  41. try:
  42. while not self.queue.empty:
  43. number = self.queue.get()
  44. if number % 2 == 0:
  45. print ("get {0} from queue Even,thread name is :{1}".format(number,self.getName()))
  46. else:
  47. self.queue.put(number)
  48. time.sleep(1)
  49. except Exception as e :
  50. raise e
  51.  
  52. def main():
  53. queue = Queue()
  54. p = Proceduer(queue = queue)
  55. p.start()
  56. p.join()
  57. time.sleep(1)
  58. c1 = Consumer_odd(queue=queue)
  59. c2 = Consumer_even(queue=queue)
  60. c1.start()
  61. c2.start()
  62. c1.join()
  63. c2.join()
  64. print ("All threads is terminate!")
  65.  
  66. if __name__ == '__main__':
  67. 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. bzoj5152 [Wc2018]通道

    题目链接 正解:不会做. 写一个爬山算法就过官方数据了(逃 具体来说就是每次随机一个根,然后迭代找最长路的那个点. 多随机几次取$max$就行了.正解以后再补.. #include <bits/ ...

  2. Centos 7 安装Anaconda3

    1.首先下载地址: https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 使用清华镜像下载速度快 2.安装 bash Anaconda3-5.1 ...

  3. VC++ MFC SDI/MDI Ribbon程序的停靠窗格被关闭后如何再次显示

    VC++ 创建基于MFC的SDI应用程序,Visual Studio风格的主界面如下图所示,在该主界面上的视图菜单下包含有队对各个可停靠窗格显示或隐藏的控制菜单项.而基于Ribbon风格的应用程序,所 ...

  4. kettle maven 配置

    <properties> <kettle.version>6.1.0.4-225</kettle.version> </properties> < ...

  5. PAT——不吉利的日期(java中date和Calendar使用)

    题目描述 在国外,每月的 13 号和每周的星期 5 都是不吉利的.特别是当 13 号那天恰好是星期 5时,更不吉利. 现在给你一个年份,请你从小到大依次输出当年所有13 号是星期 5 的月份. 输入描 ...

  6. 【洛谷P2279】[HNOI2003]消防局的设立

    消防局的设立 题目链接 贪心:每次取出深度最大的节点,若没有被覆盖到,要想覆盖它, 最优的做法显然是将它的爷爷设为消防局 (因为该节点深度为最大,选兄弟.父亲所覆盖的节点,选了爷爷后都能够覆盖) 用优 ...

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

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

  8. 锐捷交换机实验案例:vlan间互访的配置与验证

    组网需求: 1.如下图所示,某用户内网被划分为VLAN 10.VLAN 20.VLAN 30,以实现相互间的2 层隔离: 2.3 个VLAN 对应的IP 子网分别为192.168.10.0/24 .1 ...

  9. Kindeditor图片上传Controller

    asp.net MVC Kindeditor 图片.文件上传所用的Controller [HttpPost, AllowAnonymous] public ActionResult UploadIma ...

  10. Oracle 体系结构一 概述

    Oracle服务器由两个实体组成:实例和数据库. 实例由内存结构和进程组成. 它暂时存在于RAM和CPU中.当关闭运行的实例时,实例将消失的无影无踪. 数据库由磁盘上的文件组成.不管在运行状态还是停止 ...