queue队列
Queue是python标准库中的线程安全的队列(FIFO)实现,提供了一个适用于多线程编程的先进先出的数据结构,即队列,用来在生产者和消费者线程之间的信息传递。一个线程放入数据,另外一个线程取数据。
class queue.Queue(maxsize=0) #先入先出
class queue.LifoQueue(maxsize=0) #后入先出(Last in first out)
class queue.PriorityQueue(maxsize=0) #存储数据时可设置优先级的队列
队列中的方法:
1.queue.Queue.get() #获取队列数据,当队列是空的时候,会卡主,等待数据的放入,没有数据放入,会一直阻塞
get(self, block=True, timeout=None) #默认状态下,block()如果没有数据是阻塞的
import queue q = queue.Queue() q.put(1) q.put(2) print(q.get()) print(q.get()) print(q.get())
运行程序:
1
2
阻塞................
队列就是用来存取数据的,当数据取完之后,就会等待新的数据放入,get()就会一直等待,知道数据放入。要想不等待,可以使用下面方法:
当然,使用get()加上参数block=False也能实现和get_nowait()一样的功能。
block=True(False)设置当队列是空的时候,是否阻塞,True阻塞,False不阻塞,报错。timeout=None(time)设置阻塞时间,即等待一段时间,如果在这段时间内,没有数据放入,就报错。
2.get_nowait() #获取数据,如果队列是空的,则报错
import queue q = queue.Queue() q.put(1) q.put(2) print(q.get()) print(q.get()) print(q.get_nowait())
执行结果如下:
1
2
Traceback (most recent call last):
File "/home/zhuzhu/day9/队列.py", line 8, in <module>
print(q.get_nowait())
File "/usr/lib/python3.5/queue.py", line 192, in get_nowait
return self.get(block=False)
File "/usr/lib/python3.5/queue.py", line 161, in get
raise Empty
queue.Empty
上面使用,get_nowait(),如果队列是空的,则报错,可以用异常来抓取异常,然后可以继续执行。
3.queue.Queue.qsize() #判断队列里面元素的个数
import queue q = queue.Queue() print(q.qsize()) q.put(1) print(q.qsize()) q.put(2) print(q.qsize())
执行结果:
0
1
2
q.qsize()是判断队列的长度,如果长度为0,说明队列是空的,这个时候使用get()就要注意,程序会阻塞。
4.q.qut() #向队列中放入数据
put(self, item, block=True, timeout=None)
put()和get()差不多一样,put()当队列满的时候,会报错,block是设置阻塞状态是否开启,timeout是设置阻塞时间,默认一直阻塞。
5.q.empty(self) #判断队列是否是空Return True if the queue is empty, False otherwise (not reliable!).
6.q.full()
#判断队列是否是满的Return True if the queue is full, False otherwise (not reliable!)
7.put_nowait() 等价于put(block=False) #如果队列满了,则报错。Put an item into the queue without blocking
下面来看一下LifoQueue,后进先出的情形:
import queue q = queue.LifoQueue() q.put(1) q.put(2) q.put(3) print("第一个取出:",q.get()) print("第二个取出:",q.get())
上面是LifoQueue(maxsize=0)的情形,后进入的先被取出。
下面来看一下PriorityQueue的情形,有优先级的queue:
import queue q = queue.PriorityQueue() q.put((3,"alex")) q.put((1,"geng")) q.put((8,"zeng")) print("第一个取出",q.get()) print("第二个取出:",q.get()) print("第三个取出:",q.get())
执行结果:
第一个取出 (1, 'geng')
第二个取出: (3, 'alex')
第三个取出: (8, 'zeng')
上面程序中,是有优先级的放入,put((等级,内容)),存放以元组形式放入,前一个是登记,后面一个是消息。用来VIP优先级的情形。
生产者消费者模型
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。
为什么要使用生产者和消费者模式
在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。
什么是生产者消费者模式
生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。
下面来学习一个最基本的生产者消费者模型的例子:
'''生产者消费者模型就是两个线程,一个生产,另外一个消费,两者相互配合,有交互''' import queue,time,threading def producer(name): '''定义生产者模型''' count = 1 #初始化变量 while True: q.put("骨头%s" %count) #生成骨头 print("[%s]生成了骨头%s" %(name,count)) count += 1 #每次生产一个 time.sleep(0.5) #定义产能,生产效率 def consumer(name): '''定义消费者模型''' while True: print("