新一配:什么是队列?(Python队列)

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

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

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

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

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

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

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

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

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

百度百科

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

示例演示
示例情景:

假设下面有 6 个美少女,她们准备去量身高,恰好这几个妹纸是按照从高到低,从大到小排好队的。
在这里插入图片描述
每走一个去量身高,这个队列中就会少一个人。当然,队首在左,队尾在右,于是她们的变化是下面这样:
在这里插入图片描述
在这里插入图片描述

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

第一部分代码:

import queue
import threading

num_worker_threads = 5

def 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 done
q.join()

# stop workers
for i in range(num_worker_threads):
    q.put(None)
for t in threads:
    t.join()

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

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

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

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值