在python标准库中的queue模块实现了面向多生产线程、多消费线程的队列。
一、队列的三种形态
1、FIFO队列(先进先出)
1 2 3 4 5 6 7 8 9
| import queue
q = queue.Queue()
for i in range(5): q.put(i)
while not q.empty(): print(q.get())
|
2、LIFO队列(后进先出)
1 2 3 4 5 6 7 8 9
| import queue
q = queue.LifoQueue()
for i in range(5): q.put(i)
while not q.empty(): print(q.get())
|
3、Priority队列(优先级队列)
1 2 3 4 5 6 7 8 9 10 11 12
| import queue
q = queue.PriorityQueue()
q.put((1,'a')) q.put((-1,'b')) q.put((10,'c'))
while not q.empty(): print(q.get())
|
二、队列常用的方法
1、基础用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import queue
q = queue.Queue(maxsize=5)
for i in range(16): while q.full(): print(q.get()) q.put(i) print('quene size:',q.qsize())
print('-----------')
for i in range(10): while not q.empty(): print(q.get())
print('quene size:',q.qsize())
print('-----------')
for i in range(5): q.put(i)
print(q.queue.clear()) print('quene size:',q.qsize())
|
2、task_done()+join()
所有数据被get并不会解除 join 阻塞,只有全部数据都被处理完(task_done调用次数等于get次数)了才会 解除 join 阻塞。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| from threading import Thread import time import random from queue import Queue
queue = Queue(3)
class Pro_Thread(Thread): def run(self): global queue tasks = [1, 2, 3, 4, 5, 6, 7, 8] while True: try: task = tasks.pop() queue.put(task) print("生产", task, "现在队列数:", queue.qsize()) time.sleep(random.random()) except IndexError: break print("原材料已被生产完毕")
class Con_Thread(Thread): def run(self): global queue while True: if not queue.empty(): task = queue.get() time.sleep(2) queue.task_done() print("消费", task) else: break print("消费完毕")
def main(): Pro_1 = Pro_Thread() Pro_1.start() time.sleep(1) for i in range(2): Con_i = Con_Thread() Con_i.start() global queue queue.join() print("主线程结束")
if __name__ == '__main__': main()
|