python学习——python的队列

python学习——python的队列

  • 队列的实现和方法
    • 方法
    • 先进先出的代码实现
    • 后进先出的代码实现
    • 优先级队列
    • 例题

  • python的Queue模块中提供了同步、线程安全的队列
  • 包括FiFO(先入先出)、LIFO(后入先出)、优先级队列
  • 这些队列都实现了锁原语,能够在多线程中直接使用,可以使用队列来实现进程间的同步

队列的实现和方法

  • 需要导入模块:import queue 或者from queue import Queue
  • 需要创建对象:q = queue.Queue() 或者Q = Queue()(使用from导入之后才能用)
  • 创建队列的时候,需要向Queue中设置参数,表示队列的长度;不传参数,表示可以无限往队列中添加数据

方法

  • qsize(),返回当前队列中包含的消息数量
  • empty(),如果队列为空,返回True,或者False
  • full(),如果队列满了,返回True或者False
  • get(),获取队列,timeout参数可以设置等待时间
  • get_nowait(),相当于get方法
  • put(),写入队列,其中存在三个参数
    • item,表示塞入队列中的数值
    • block=True,表示是否等待,默认等待
    • timeout=None,表示等待时间,默认None
  • put_nowait(),相当于put方法
    • 只有item参数,即塞入队列中的数值
  • task_done(),在完成一项工作之后,使用这个方法向队列发出一个信号,表示该任务执行完毕
  • join(),实际上分意味着等到队列中所有任务执行完毕之后,再往下继续执行,否则就一直等待
    • 注意:join的的判断依据,不仅仅是指队列中没有数据,数据get出去之后,要使用task_done发送一个信号,表示任务执行完毕
    • task_done执行必须在join之前,且task_done执行的次数要大于等于任务个数,例如插入三次或者获取数据三次,就要写三条语句,否则会在join处阻塞,取法向下运行

先进先出的代码实现

import  queue

q = queue.Queue(3)  # 创建队列,10表示队列长度
for i in range(10,7,-1):
    q.put(i)
    # 如果队列满了,就会等待(默认)
    # 如果设置了不等待,就不会等待,队列已满,就报错
    # 和put_nowait一样
print("num:",q.qsize())
print("is null:",q.empty())
print("是否满队列:",q.full())
print("队列元素:",q.get()) # 先添加进去的先出来
print("队列元素:",q.get())
print("队列元素:",q.get())
# 获取完之后,也会等待(默认),参数和put一样
# get_nowait也只有item参数
# 队列无元素,也和get设置了不等待一样,报错
print("获取完,队列是否为空:",q.empty())
q.task_done() # 获取完数据之后,就要发一个信号
q.task_done()
q.task_done()
a = q.join() # 如果信号数小于执行语句,就会一直等待
print("join的执行结果:",a)

***********run_result***********
num: 3
is null: False
是否满队列: True
队列元素: 10
队列元素: 9
队列元素: 8
获取完,队列是否为空: True
join的执行结果: None

后进先出的代码实现

  • 后进先出,需要使用LifoQueue方法,代码如下
from  queue import LifoQueue

q = LifoQueue(3)  # 创建队列,10表示队列长度
for i in range(10,7,-1):
    q.put(i)
    # 如果队列满了,就会等待(默认)
    # 如果设置了不等待,就不会等待,队列已满,就报错
    # 和put_nowait一样
print("num:",q.qsize())
print("is null:",q.empty())
print("是否满队列:",q.full())
print("队列元素:",q.get()) # 后进先出
print("队列元素:",q.get())
print("队列元素:",q.get())
# 获取完之后,也会等待(默认),参数和put一样
# get_nowait也只有item参数
# 队列无元素,也和get设置了不等待一样,报错
print("获取完,队列是否为空:",q.empty())
q.task_done() # 获取完数据之后,就要发一个信号
q.task_done()
q.task_done()
a = q.join() # 如果信号数小于执行语句,就会一直等待
print("join的执行结果:",a)

优先级队列

  • 插入元素的时候要插入元组,(优先级,数据)
  • 获取数据的时候,按照优先级的大小,从小到大获取
from queue import PriorityQueue

q = PriorityQueue(3)  # 创建队列,10表示队列长度
data = {2:5,0:10,1:6}
for k,v in data.items():
    q.put((k,v))
    # 优先级队列设置元素:元组形式(优先级,数值)
print("num:",q.qsize())
print("is null:",q.empty())
print("是否满队列:",q.full())
print("队列元素:", q.get())  # 按照优先级的大小,由小到大获取
print("队列元素:", q.get())  # 获取的结果是个数组
print("队列元素:",q.get())
# 获取完之后,也会等待(默认),参数和put一样
# get_nowait也只有item参数
# 队列无元素,也和get设置了不等待一样,报错
print("获取完,队列是否为空:",q.empty())
q.task_done() # 获取完数据之后,就要发一个信号
q.task_done()
q.task_done()
a = q.join() # 如果信号数小于执行语句,就会一直等待
print("join的执行结果:",a)
***************run_result***************
num: 3
is null: False
是否满队列: True
队列元素: (0, 10)
队列元素: (1, 6)
队列元素: (2, 5)
获取完,队列是否为空: True
join的执行结果: None

例题

  • 1,使用一个队列来存储商品
  • 2,创建一个专门生产圣品的线程类,当商品数量小于50时,开始生产商品
  • 每次生产200个商品,每生产一轮,暂停1s
  • 3,创建一个专门消费商品的线程类,当商品数量大于10时,开始消费
  • 循环消费,每次消费3个,当商品个数小于10时,暂停2s
  • 4,创建一个线程生产商品,5个线程消费商品
import threading
from queue import Queue
import time

q = Queue()

class Product(threading.Thread):
    """ 生产者线程类 """

    def  run(self):
        count = 0
        while True:
            if q.qsize() <50:
                for i in range(200):
                    count+=1
                    goods = "第{}个商品".format(count)
                    q.put(goods)
                    print("生产:",goods)
            time.sleep(2)


class Consumer(threading.Thread):
    """ 消费者线程类 """

    def run(self):
        while True:
            if q.qsize() >10:
                for i in range(3):
                    a = q.get()
                    print(" 获得商品:", a)
            else:
                time.sleep(2)

p = Product()
p.start()
for i in range(5):
    c = Consumer()
    c.start()
  • 不用重写的方式来做:
import threading
from queue import Queue
import time

q = Queue()

class ProAndCons:

    def product_goods(self):
        while True:
            print(q)
            if q.qsize()<50:
                for i in range(200):
                    goods = "第{}个元素".format(i)
                    q.put(goods)
                    print("goods:",goods)
            time.sleep(2)


    def cons_goods(self):
        while True:
            print(q)
            print(q.qsize())
            if q.qsize() >=10:
                for i in range(3):
                    g = q.get()
                    print("商品:",g)
            else:
                time.sleep(2)

t = threading.Thread(target=ProAndCons().product_goods)
t.start()
time.sleep(10)
for i in range(5):
    print("11")
    c = threading.Thread(target=ProAndCons().cons_goods)
    c.start()

你可能感兴趣的:(python,学习,开发语言)