10人队列视频 (queue清空队列)

创建一个“队列”对象

import Queue

myqueue = Queue.Queue(maxsize = 10)

Queue.Queue类即是一个队列的同步实现。队列长度可为无限或者有限。可通过Queue的构造函数的可选参数maxsize来设定队列长度。如果maxsize小于1就表示队列长度无限。

myqueue.put(10):将一个值放入队列中调用队列对象的put()方法在队尾插入一个项目。put()有两个参数,第一个item为必需的,为插入项目的值;第二个block为可选参数,默认为1。如果队列当前为空且block为1,put()方法就使调用线程暂停,直到空出一个数据单元。如果block为0,put方法将引发Full异常。

myqueue.get():将一个值从队列中取出,调用队列对象的get()方法从队头删除并返回一个项目。可选参数为block,默认为True。如果队列为空且block为True,get()就使调用线程暂停,直至有项目可用。如果队列为空且block为False,队列将引发Empty异常。

queue模块有三种队列:

1、python queue模块的FIFO队列先进先出。

2、LIFO类似于堆。即先进后出。

3、还有一种是优先级队列级别越低越先出来。

针对这三种队列分别有三个构造函数:

1、class Queue.Queue(maxsize) FIFO # 先进先出

2、class Queue.LifoQueue(maxsize) LIFO #后进先出

3、class Queue.PriorityQueue(maxsize) 优先级队列 q.put[1,3] # 插入3,优先级为1

介绍一下此包中的常用方法:

Queue.qsize() 返回队列的大小

Queue.empty() 如果队列为空,返回True,反之False

Queue.full() 如果队列满了,返回True,反之False

Queue.full 与 maxsize 大小对应

Queue.get([block[, timeout]])获取队列,timeout等待时间

Queue.get_nowait() 相当Queue.get(False)

非阻塞 Queue.put(item) 写入队列,timeout等待时间

Queue.put_nowait(item) 相当Queue.put(item, False)

Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号

Queue.join() 实际上意味着等到队列为空,再执行别的操作

实例:

#!/usr/bin/env python3

# -*- coding: utf-8 -*-

# @Time : 2018/5/12 10:27

# @Author : CaiChangEn

# @Email : mail0426@163.com

# @Software: PyCharm

import threading,time,queue

import time

lst=[1,2,3,4,5,6,7,8,9]

# 常规方式

def cce():

# lock.acquire()

while lst:

last=lst[-1]

time.sleep(0.5)

lst.remove(last)

print(last,'list:',lst)

# lock.release()

# lock=threading.RLock()

t1=threading.Thread(target=cce)

t2=threading.Thread(target=cce)

t1.start()

t2.start()

# 可以看出在这种情况,使用多线程来删除列表的最后一个元素如果不加入锁是会报错的

# 使用线程队列

lst=[1,2,3,4,5,6,7,8,9]

q=queue.Queue(maxsize=10) # maxsize 最大的数据,除非另外一个线程从我们的队列里面q.get走一个数据才可以进一个数据

for i in lst:

q.put(i,block=False) # 如果block=False 那么队列满了,就会抛出一个full的错误

while True:

data=q.get(block=False) # 如果block=False,那么对了为空,再取就会报错

print(data)

# 可以看出,现在我们的while是没有退出的,一直停留在q.get的阶段,队列是用来解决线程安全的,现在队列就一直停留在这里,等待有人向我们的队列put数据

生产者消费者模型

为什么要使用生产者和消费者模式

在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。

什么是生产者消费者模式

生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

这就像,在餐厅,厨师做好菜,不需要直接和客户交流,而是交给前台,而客户去饭菜也不需要不找厨师,直接去前台领取即可,这也是一个结耦的过程。

实例一

#!/usr/bin/env python3

# -*- coding: utf-8 -*-

# @Time : 2018/5/12 10:27

# @Author : CaiChangEn

# @Email : mail0426@163.com

# @Software: PyCharm

import time,random

import queue,threading

q = queue.Queue() # 服务员

def Producer(name): # 生成包子队列

count = 0

while count <10: # 只生产10个包子

print("making........") # 开始做包子

time.sleep(random.randrange(3))

q.put(count) # 做了几个包子

print('Producer %s has produced %s baozi..' %(name, count)) #打印队列中有几个包子

count +=1

print("ok......") # 打印制作完成

def Consumer(name): # 客户吃包子的函数

count = 0

while count <10:

time.sleep(random.randrange(4))

if not q.empty(): # 如果队列中有包子

data = q.get() # 客户吃一个包子

print('\033[32;1mConsumer %s has eat %s baozi...\033[0m' %(name, data))

else: # 如果队列中没有包子

print("-----no baozi anymore----")

count +=1

p1 = threading.Thread(target=Producer, args=('A',))

c1 = threading.Thread(target=Consumer, args=('B',))

c2 = threading.Thread(target=Consumer, args=('C',))

c3 = threading.Thread(target=Consumer, args=('D',))

p1.start()

c1.start()

c2.start()

c3.start()

实例二

#!/usr/bin/env python3

# -*- coding: utf-8 -*-

# @Time : 2018/5/12 10:27

# @Author : CaiChangEn

# @Email : mail0426@163.com

# @Software: PyCharm

import time,random

import queue,threading

q = queue.Queue() # 服务员

def Producer(name): # 生成包子队列

count = 0

while count <10: # 只生产10个包子

print("making........") # 开始做包子

time.sleep(random.randrange(3))

q.put(count) # 做了几个包子

print('Producer %s has produced %s baozi..' %(name, count)) #打印队列中有几个包子

count +=1

q.task_done() # 如果厨师做完了,就可以向想q.join发送信号了

print("ok......") # 打印制作完成

def Consumer(name): # 客户吃包子的函数

count = 0

while count <10:

time.sleep(random.randrange(4))

print('waiting...')

q.join() # 如果没有接收到信息,那么就阻塞,如果接收到了就继续往下走

data = q.get() # 客户吃一个包子

print('\033[32;1mConsumer %s has eat %s baozi...\033[0m' %(name, data))

count +=1

p1 = threading.Thread(target=Producer, args=('A',))

c1 = threading.Thread(target=Consumer, args=('B',))

c2 = threading.Thread(target=Consumer, args=('C',))

c3 = threading.Thread(target=Consumer, args=('D',))

p1.start()

c1.start()

c2.start()

c3.start()

# 所有的人等待厨师的信号之后再吃包子