一、多进程的消息队列

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

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

  操作系统提供了很多机制来实现进程中的通信,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. 使用npoi插件将excel文件导出

    大致流程:前端使用URL地址的方式跳转到action后返回file类型数据 js: window.location.href = '/Home/index?Id=' + id 后台代码: /// &l ...

  2. AlexNet 分类 FashionMNIST

    from mxnet import gluon,init,nd,autograd from mxnet.gluon import data as gdata,nn from mxnet.gluon i ...

  3. 开关WI-Fi显示列表

    实现效果: 使用方法: Show-NetList     #显示Wi-Fi列表 Show-NetList -off #关闭显示 (如图) 实现代码: function Show-NetList { P ...

  4. 使用QT开发GoogleMap瓦片显示和下载工具(2)——Google地图瓦片投影和获取网址解析

    这篇主要说的是Google地图采用的投影方式,瓦片划分方式以及如何从给定的经纬度获取瓦片的数据的网址.所有资料均来自于网络,并亲自试验可行. Google地图投影 首先是地图投影问题,因为地球本身是一 ...

  5. C# Path类 FileStream(文件流) 与 File(文件) 读取的区别

    1.采用文件流读取数据是一点一点从文件中读取数据对内存的压力相对较小;而采用文件读取数据是一下全部读取过来对内存造成的压力相对较大 2.File读取: string str = @"E:\Q ...

  6. 【翻译】Django Channels 官方文档 -- Tutorial

    Django Channels 官方文档 https://channels.readthedocs.io/en/latest/index.html 前言: 最近课程设计需要用到 WebSocket,而 ...

  7. heatmap for arcgisjsapi

    在arcgis for js api 环境下使用heatmap插件. 由于最新的heatmap没有提供 for arcgisjsapi  插件,懒得研究新版本代码,所以这里用的还是老版本的heatma ...

  8. java并发编程之CompletionService

    应用场景当向Executor提交多个任务并且希望获得它们在完成之后的结果,如果用FutureTask,可以循环获取task,并调用get方法去获取task执行结果,但是如果task还未完成,获取结果的 ...

  9. idea中ssm自动配置

    自动生成 只需要创建好maven项目,然后创建一个类Test,复制代码粘贴即可 使用注意: 代码 import java.io.*; public class Test { //包名格式 //列如配置 ...

  10. Knowledge Point 20180305 Java程序员详述编码Unicode

    Unicode Unicode(统一码.万国码.单一码)是计算机科学领域里的一项业界标准,包括字符集.编码方案等.Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设 ...