Python_学习之内置队列Queue

Python中的队列Queue

我们在工作中有时需要将数据保存在内存里,但有时需要对保存的数据顺序有要求,我们一般采用有序字典,其实也可以使用内置队列解决,而队列都是线程安全的,更高效。

  • 1. 线程Queue,也就是普通的Queue,模块queue
  • 2. 进程Queue,在多进程与多线程时使用,模块from multiprocessing import Queue

Queue的种类

模块queue都有的一下方法

Queue().qsize() 返回队列的大小
Queue().empty() 如果队列为空,返回True,否则False,如果在多进程的异步中,不准
Queue().full()  如果队列满了,返回True,否则False,如果在多进程的异步中,不准
Queue.put(item,block=True,timeout=None) 向队列放入对象
    - item :对象元素
    - block:默认为True,代表队列满了就一直等待阻塞,False则为不阻塞,满了会直接主动抛出异常
    - timeout: 默认为None,阻塞等待的时间,如何设置block为True,时间到了,还不能放,抛出异常
Queue().put_nowait(item) 放入元素,如果队列已满,则不等待直接抛出异常
Queue().get(block=True, timeout=None) 返回队列中的元素,队列中为空,则阻塞一直等待有值为止,设置了timeout则到时间还没有抛出异常
Queue().get_nowait()  队列为空时,如果没有直接抛异常,不等待

Queue().join()   阻塞调用线程,知道队列中的所有任务被处理掉
只要有数据被加入队列,未完成的任务数就会增加。当消费者线程调用task_done()(意味着有消费者取得任务并完成任务),未完成的任务数就会减少。当未完成的任务数降到0,join()解除阻塞

Queue().task_done()
意味着之前入队的一个任务已经完成。由队列的消费者线程调用。每一个get()调用得到一个任务,接下来的task_done()调用告诉队列该任务已经处理完毕。
如果当前一个join()正在阻塞,它将在队列中的所有任务都处理完时恢复执行(即每一个由put()调用入队的任务都有一个对应的task_done()调用)

FIFO

  • queue.Queue(maxsize=0)

first in first out ,先进先出。maxsize指定队列中能存放元素的上限数字,一旦达到上限,插入会导致阻塞,直到队列中的数据被消费掉。如果配置maxsize小于或为0时,代表队列大小无上限,默认为0。

from queue import Queue

# 创建队列对象
q = Queue(maxsize=0)
# 在队列尾部插入元素
q.put("0000")
q.put("1111")
q.put("2222")
print('LILO队列中所有的元素为:', q.queue)  # deque([0, 1, 2])
# 返回并删除队列头部元素
print(q.get())  # 0
print(q.qsize())  # 2 获取队列的元素个数,因取出来一个,所以还剩下2
print(q.queue)

LIFO

-queue.Queue(maxsize=0)

last in first out ,后进先出,类似栈。maxsize同上。

from queue import LifoQueue  

lifoQueue = LifoQueue()
lifoQueue.put(1)
lifoQueue.put(2)
lifoQueue.put(3)
print('LIFO队列', lifoQueue.queue)
# 返回并删除队列尾部元素
print(lifoQueue.get())  # 3
print(lifoQueue.get())  # 2

Priority

-queue.PriorityQueue(maxsize=0)

优先队列。maxsize同上。q.put((priority_number,item)),默认priority_number越小,优先级越高,可以通过__lt__来改变

import queue
import threading


class Job:
    def __init__(self, priority, desc):
        self.priority = priority
        self.desc = desc
        print("New Job:", desc)
        return

    def __eq__(self, other):
        try:
            return self.priority == other.priority
        except AttributeError:
            return NotImplemented

    def __lt__(self, other):
        try:
            return self.priority > other.priority
        except AttributeError:
            return NotImplemented


def process_Job(q):
    while True:
        next_job = q.get()
        print(next_job.desc)
        q.task_done()


q = queue.PriorityQueue()

q.put(Job(5, "Five Job"))
q.put(Job(15, "Fifteen Job"))
q.put(Job(1, "One Job"))

workers = [
    threading.Thread(target=process_Job, args=(q,)),
    threading.Thread(target=process_Job, args=(q,)),
]

for work in workers:
    work.setDaemon(True)
    work.start()

q.join()

这里,我们默认数值越大优先级越高,可以看到15先执行,然后再是5,1任务。这个例子展现了有多个线程在处理任务时,要根据get()时队列中元素的优先级来处理。
https://blog.csdn.net/u013288190/article/details/128810536

双向队列

  • deque

队列两端都可以删除和新增

from collections import deque

dequeQueue = deque(['Eric', 'John', 'Smith'])
print(dequeQueue)
dequeQueue.append('Tom')  # 在右侧插入新元素
dequeQueue.appendleft('Terry')  # 在左侧插入新元素
print(dequeQueue)
dequeQueue.rotate(2)  # 循环右移2次
print('循环右移2次后的队列', dequeQueue)
dequeQueue.popleft()  # 返回并删除队列最左端元素
print('删除最左端元素后的队列:', dequeQueue)
dequeQueue.pop()  # 返回并删除队列最右端元素
print('删除最右端元素后的队列:', dequeQueue)

多进程与多线程使用queue

 
import multiprocessing as mp
import threading as td
import time
 
def job(q):
    res = 0
    for i in range(10000000):
        res += i+i**2+i**3
    q.put(res) # queue
 
def multicore():
    q = mp.Queue()
    p1 = mp.Process(target=job, args=(q,))
    p2 = mp.Process(target=job, args=(q,))
    p1.start()
    p2.start()
    p1.join()
    p2.join()
    res1 = q.get()
    res2 = q.get()
    print('multicore:' , res1+res2)
 
def normal():
    res = 0
    for _ in range(2):#线程或进程都构造了两个,进行了两次运算,所以这里循环两次
        for i in range(10000000):
            res += i+i**2+i**3
    print('normal:', res)
 
def multithread():
    q = mp.Queue()
    t1 = td.Thread(target=job, args=(q,))
    t2 = td.Thread(target=job, args=(q,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    res1 = q.get()
    res2 = q.get()
    print('multithread:', res1+res2)
 
if __name__ == '__main__':
    st = time.time()
    normal()
    st1= time.time()
    print('normal time:', st1 - st)
    multithread()
    st2 = time.time()
    print('multithread time:', st2 - st1)
    multicore()
    print('multicore time:', time.time()-st2)
 
''' 运算结果如下
normal: 4999999666666716666660000000
normal time: 15.330998182296753
multithread: 4999999666666716666660000000
multithread time: 14.570075511932373
multicore: 4999999666666716666660000000
multicore time: 8.55050778388977
'''
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容