龙空技术网

什么是队列?(Python队列)

咪哥杂谈 127924

前言:

此刻咱们对“python线程池和队列”可能比较重视,小伙伴们都想要知道一些“python线程池和队列”的相关资讯。那么小编同时在网络上搜集了一些有关“python线程池和队列””的相关资讯,希望咱们能喜欢,小伙伴们快快来学习一下吧!

前言

上篇文章介绍了 Python 中的多线程。今天来介绍下编程中常会用到的一个数据结构 - 队列。

不知道大家是否还记得什么是数据结构呢?在很早很早以前,Python小课堂的初期,讲了许多 Python 原生的数据结构。比如 list、tuple、dict 等。。。

既然叫数据结构,实际上就是为了给计算机存储数据用的一种结构体。不同的数据结构都有其不同的特点。那今天就来简单地聊聊队列!

队列的概念

抛开计算机知识体系,在咱们的生活中,队列这个词其实挺好想象的,因为无时无刻都可以见到。比如等公交的时候,需要排队。比如买东西交钱的时候,也要排队。在这些例子中,由人们有序形成的队形就叫队列。

生活中的排队,有没有什么特性而言呢?大家可以思考下,再往下看。

普通队列的特性,即先进先出(FIFO,first in first out)。对应到生活中,怎么理解这个先进先出?其实很好理解。

拿排队买东西来说,每次排在队首的人,交完钱肯定是当前队列中第一个离开收银台的人。当队首的人离开了,那么后面的所有人都要往前走,继续结账。

对应到计算机中的队列,就是因为第一个人先排的队,所以他第一个交完钱就可以离开了,即先进先出。(多说句,计算机世界许多东西其实就是抽象的现实世界示例。)

心细的同学会发现,在上面将普通两字标粗了,那一定还有一些其它的常用特殊队列,比如优先级队列。(PriorityQueue)

这次拿去银行办业务来举例。生活中我们去银行办理业务,一般都需要去机器拿号,然后等待着柜台业务人员叫号。叫到你,你就过去处理就行了。但是银行是有 vip 服务的,拥有 vip 权益的人可以更快的享受到业务办理,也就是说人家比你有更高的优先权。vip特权通道,你值得拥有!

了解了生活中的例子,再来看看比较专业的定义:

优先级队列(priority queue) 是0个或多个元素的集合,每个元素都有一个优先权,对优先级队列执行的操作有(1)查找(2)插入一个新元素 (3)删除 一般情况下,查找操作用来搜索优先权最大的元素,删除操作用来删除该元素 。对于优先权相同的元素,可按先进先出次序处理或按任意优先权进行。

百度百科

也就是说,在优先级队列中,每个人都有一个优先权对应,谁的优先权高,谁就会先被处理。大家了解即可。

示例演示

示例情景:

假设下面有 6 个美少女,她们准备去量身高,恰好这几个妹纸是按照从高到低,从大到小排好队的。

每走一个去量身高,这个队列中就会少一个人。当然,队首在左,队尾在右,于是她们的变化是下面这样:

。。。。。。省略,直到:

代码演示

是不是好多人看到这里就不打算看了。。不是让你来看美少女的喂。。。下面才是重点~

第一部分代码:

import queueimport threadingnum_worker_threads = 5def do_work(beauty_dict):    print(f"妹纸名字{beauty_dict['name']},年龄{beauty_dict['age']}")def worker():    while True:        item = q.get()        if item is None:            break        do_work(item)        q.task_done()

简单的讲解下,在 Python3 中,有个模块叫 queue。里面实现了几个队列的数据结构。首先看 do_work() 函数,其中它就是用来打印妹子姓名和年龄的。worker() 函数中写了一层死循环,只要队列中有妹纸的数据,就一直执行打印,直到队列中的妹纸都没了,就跳出。

第二部分代码:

q = queue.Queue()threads = []for i in range(num_worker_threads):    t = threading.Thread(target=worker)    t.start()    threads.append(t)beauty_girls = [{"name": "小H", "age": 23},                {"name": "小E", "age": 22},                {"name": "小D", "age": 21},                {"name": "小C", "age": 20},                {"name": "小B", "age": 19},                {"name": "小A", "age": 18},                ]for item in beauty_girls:    q.put(item)# block until all tasks are doneq.join()# stop workersfor i in range(num_worker_threads):    q.put(None)for t in threads:    t.join()

首先创建队列,其次,让这 6 个美少女开始依次排入到队列中,开启多线程去执行 worker() 这个函数。worker() 函数就是第一部分代码中,从队列里一个个取出妹纸,在调用 do_work() 打印她们的姓名和年龄。

关于队列的 join() 方法,可以看到官方给的英文注释,大意是当所有任务完成时才继续执行后面的代码,否则处于阻塞状态。

代码中涉及的方法,老规矩,希望大家可以自己去查阅 Python 官方文档,搜索 queue 即可看到。当然如果懒得动手的话,笔者这里截图几个常用方法:

将妹纸放入队列中:

从队列中获取妹纸:


获取队列中妹纸的个数:

总结

通过两篇文章,简单的介绍了一下多线程和队列,目的是为了接下来的多线程队列爬虫示例做准备,如果对这些不了解的话,在后面的代码中是很难看懂的。

关于队列的使用,最常用的方法应该就是放入、获取、判断队列的大小。其实这三点在大部分数据结构里都是常用的操作,熟练掌握即可。

本章完整代码,就是文中第一部分和第二部分的代码拼接,因为太长,所以分开讲了下。

如果大家有什么问题想沟通,可以留言交流哈!

标签: #python线程池和队列