队列的类型和常用方法

队列是一种数据结构,它类似于列表。但列表是线程不安全的,而队列是线程安全的。

python的queue(python3,python2为Queue)提供了3种队列:

  • Queue:先进先出型(First In First Out)。
  • LifoQueue:后进先出型(Last In First Out)。
  • PriorityQueue:优先级型,为队列中的元素自定义优先级,按照优先级获取元素。

每种队列的构造方法都有一个maxsize的属性,默认为0,该属性用来指定队列存放的最大元素个数。如果为0或小于0,则队列是无限长的。

队列中的方法:

  • q.put(10):将某个元素放到队列中。该方法中的参数item(即要存放的元素)是必须指定的;

    • 参数block=True,该参数是否采取阻塞的方式向队列中放置元素。如果block=True,则put方法会在队列已经满了的情况(没有空余位置)下阻塞,直到队列中空出位置后再将元素放置到队列中;如果block=False,不论队列是否有空余位置都会尝试将元素放到队列中,当队列已满时会抛出“满队列异常(Full exception)”。q.put_nowait()方法相当于q.put(block=False)。
    • 参数timeout=None,当该参数被设置为x(大于或等于0)时,put方法最多会阻塞x秒,之后尝试向队列中存放元素,如果队列已满,则会抛出Full exception。
  • q.get():对于Queue创建的队列来说,该方法会从队列头部获取并删除一个元素(最先进入队列的元素)。该方法同样也有可选参数block=True。默认情况下(True),该方法会在队列为空时阻塞,直到有元素被放入到队列中;当block=False时,该方法不会阻塞,如果队列为空,则会抛出"空队列异常(Empty exception)“。q.get_nowait()方法相当于q.get(block=False)。
  • q.task_done():在完成某项队列操作后向队列发送一个信号。
  • 判断队列属性的方法有:
    • q.qsize():返回队列的长度;
    • q.empty():如果队列为空,返回True,否则返回False。
    • q.full():如果队列满了,返回True,否则返回False。

示例1:先进先出型,使用多个线程从同一队列中取出元素

 import threading, time, queue

 class MyThread(threading.Thread):

     def run(self):

         while True:
if q.qsize() > 0:
item = q.get() # 从队列中取出元素
print("%s::取出的元素---->%s at %s" % (self.name, item, time.ctime()))
time.sleep(2)
else:
print("队列已空,无法取出元素")
break if __name__ == '__main__': q = queue.Queue() for i in range(10):
q.put(i) # 将0-9的数字放到队列q中 threads = [] for i in range(3):
threads.append(MyThread()) for t in threads:
t.start() for t in threads:
t.join() print("main thread ending....")

打印结果如下:

Thread-1::取出的元素---->0 at Tue Mar 26 16:33:41 2019
Thread-2::取出的元素---->1 at Tue Mar 26 16:33:41 2019
Thread-3::取出的元素---->2 at Tue Mar 26 16:33:41 2019
Thread-2::取出的元素---->3 at Tue Mar 26 16:33:43 2019
Thread-1::取出的元素---->4 at Tue Mar 26 16:33:43 2019
Thread-3::取出的元素---->5 at Tue Mar 26 16:33:43 2019
Thread-3::取出的元素---->6 at Tue Mar 26 16:33:45 2019
Thread-1::取出的元素---->7 at Tue Mar 26 16:33:45 2019
Thread-2::取出的元素---->8 at Tue Mar 26 16:33:45 2019
Thread-2::取出的元素---->9 at Tue Mar 26 16:33:47 2019
队列已空,无法取出元素
队列已空,无法取出元素
队列已空,无法取出元素
main thread ending.... ***Repl Closed***

可以看到,3个线程循环的从队列中取出元素,元素获取的顺序与放入队列的顺序一致。

示例2:LiFoQueue(后进先出队列)与PriorityQueue(优先级队列)

 import queue

 def my_LiFo_queue():
q = queue.LifoQueue()
for i in range(5):
q.put(i) while not q.empty():
print("LiFo queue -->", q.get()) def my_proirity_queue():
q = queue.PriorityQueue()
q.put(10)
q.put(7)
q.put(3)
q.put(1) while not q.empty():
print("proirity queue-->", q.get()) my_LiFo_queue() my_proirity_queue()

打印结果如下所示:

LiFo queue --> 4
LiFo queue --> 3
LiFo queue --> 2
LiFo queue --> 1
LiFo queue --> 0
proirity queue--> 1
proirity queue--> 3
proirity queue--> 7
proirity queue--> 10 Process finished with exit code 0

对于PriorityQueue,我们可以自定义它的内部比较方法,为每个元素指定优先级后get()方法就会根据优先级来获取队列中的元素。

 import queue

 class Skill(object):
def __init__(self, priority, description):
self.priority = priority # 优先级参照
self.description = description def __lt__(self, other): # 重新定义实例间的比较规则(<)
return self.priority < other.priority def __str__(self): # 重新定义该类实例的打印信息
return "(%s, '%s')" % (self.priority, self.description) def PriorityQueue_class():
q = queue.PriorityQueue()
q.put(Skill(7, 'proficient7'))
q.put(Skill(5, 'proficient5'))
q.put(Skill(6, 'proficient6'))
q.put(Skill(10, 'expert'))
q.put(Skill(1, 'novice'))
print('end')
while not q.empty():
print(q.get()) PriorityQueue_class()

打印结果如下所示:

end
(1, 'novice')
(5, 'proficient5')
(6, 'proficient6')
(7, 'proficient7')
(10, 'expert') Process finished with exit code 0

可见,get方法是按照优先级从低到高的顺序依次取出元素的。

参考:

https://www.cnblogs.com/itogo/p/5635629.html

https://www.cnblogs.com/saolv/p/9502124.html

线程中的队列(queue)的更多相关文章

  1. 线程回调,线程中的队列,事件,greenlet模块,gevent模块,自定义补丁, 单线程实现并发,协程

    1.线程回调 在线程池/进程池每次提交任务,都会返回一个表示任务的对象,Future对象Future对象具备一个绑定方法,add_done_callback 用于指定回调函数 add 意味着可以添加多 ...

  2. Java 中的队列 Queue

    一.队列的定义 我们都知道队列(Queue)是一种先进先出(FIFO)的数据结构,Java中定义了java.util.Queue接口用来表示队列.Java中的Queue与List.Set属于同一个级别 ...

  3. Java中的队列Queue,优先级队列PriorityQueue

    队列Queue 在java5中新增加了java.util.Queue接口,用以支持队列的常见操作.该接口扩展了java.util.Collection接口. Queue使用时要尽量避免Collecti ...

  4. 标准模板库中的队列(queue)

    //C++数据结构与算法(第4版) Adam Drozdek 著  徐丹  吴伟敏<<清华大学出版社>> 队列容器默认由deque实现,用户也可以选择list容器来实现.如果用 ...

  5. Java中使用队列Queue

    示例代码: Queue<Integer> queue = new LinkedList<Integer>(); for (int i = 1; i <= 100; i + ...

  6. 关于队列queue

    1.在多线程和多进程中都有queue.调用方式不同,使用方式一致: 线程中: import queue q = queue.Queue(maxsize = 2) 进程中: from multiproc ...

  7. python并发编程之多进程、多线程、异步、协程、通信队列Queue和池Pool的实现和应用

    什么是多任务? 简单地说,就是操作系统可以同时运行多个任务.实现多任务有多种方式,线程.进程.协程. 并行和并发的区别? 并发:指的是任务数多余cpu核数,通过操作系统的各种任务调度算法,实现用多个任 ...

  8. Java线程:堵塞队列与堵塞栈

    一.堵塞队列 Java定义了堵塞队列的接口java.util.concurrent.BlockingQueue,堵塞队列是一个指定长度的队列,当试图向队列中添加元素而队列已满,或者是想从队列移出元素而 ...

  9. python端口扫描用多线程+线程安全的队列+Thread类实现

    用线程安全的队列Queue实现扫描端口数据存储 用多线程扫描端口 用Thread类实现程序组织 #coding:utf-8 import sys import socket import sys im ...

随机推荐

  1. CPU TFLOPS 计算

    CPU TFLOPS 计算 姚伟峰 yaoweifeng0301@126.com] http://www.cnblogs.com/Matrix_Yao/ 深度学习任务是一个计算密集型任务,所以很关注计 ...

  2. computer browser服务无法启动 错误1068 依存服务或组无法启动

    两台电脑电脑之间传送大文件,发现局域网内共享文件,需要设置文件夹共享,需要开启 Computer Browser服务,而Computer Browser服务项的依存服务项是server服务和works ...

  3. tensorflow 升级到1.9-rc0,生成静态图frozen graph.pb本地测试正常, 在其他版本(eg1.4版本)或者android下运行出错NodeDef mentions attr 'dilations' not in Op<name=Conv2D; signature=input:T, filter:T -> output:T; attr=T:type,allowed=[DT_

    这时节点定义找不到NodeDef attr 'dilations' not in,说明执行版本的NodeDef不在节点定义上,两个不一致,分别是执行inference的代码和生成静态图节点不一致(当然 ...

  4. [TestNG] [WARN] Ignoring duplicate listener : org.testng.IDEATestNGRemoteListenerEx

    1. 使用6.10,和6.14.3版本testng,出现多条warn信息 [TestNG] [WARN] Ignoring duplicate listener : org.testng.IDEATe ...

  5. rsync镜像命令

    rsync -e 'ssh -p 19809' -av wwwroot root@3.3.3.3:/home/download/ 参数详解 编辑 -v, --verbose 详细模式输出 -q, -- ...

  6. IIS启动应用程序池报错"服务无法在此时接受控制信息"

    用管理员方式打开命令行 输入命令netsh winsock reset 这个命令在百科上的解释是 netsh winsock reset命令,作用是重置 Winsock 目录.如果一台机器上的Wins ...

  7. CCS 6新建文件自动生成注释

    对于CCS6,可以通过配置,达到新建源文件或者头文件时,自动生成适当的注释: 一.新建源文件自动生成配置. 在某个文件夹下右击选择 New - Source File. 点击 Configure,再选 ...

  8. Windows防火墙开启ping,禁ping的配置

    当我通过本机Ping另一台在同一局域网内(即在同一网段)的计算机时,发现,如果防火墙开启的话,无论如何也ping不通.一旦关闭防火墙就可以ping通了.这是为什么呢?究竟该怎么设置呢? 原因是这样的, ...

  9. 关于webApi 跨域请求

    先说一下我的项目,后台单纯的webApi,前端采用Vue+axios, 说一下我遇见的问题,axios请求webAPI但是浏览器会报错,大致上就是不允许跨域请求. 于是查找解决办法发现以下代码(web ...

  10. XML Linq 学习笔记

    XML如下: <?xml version="1.0" encoding="utf-8"?> <Dishes> <Dish> ...