Python中,队列是线程间最常用的交换数据的形式。queue模块是提供队列操作的模块,虽然简单易用,但是不小心的话,还是会出现一些意外。
1、queue简单说明
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 '''
5 queue队列:常用在多线程里面,能够直接在线程安全的在多个线程之间进行数据交换,不需要当参数传递
6
7 class queue.Queue(maxsize=0) #先进先出
8 class queue.LifoQueue(maxsize=0) #后进先出 last in first out
9 class queue.PriorityQueue(maxsize=0) #存储数据时可以设置优先级的队列
10
11 队列中可以存放任意类型数据
12
13 队列常用方法:
14 put(x) 将x存储到队列,存不下就就会阻塞,timeout设置阻塞超时时间,不设置会一直阻塞
15 put_nowait(x) 不阻塞,放不进去就报错
16 get() 从队列中取出一个值(先进先出),其余的跟put一样
17 get_nowait() 从队列中取出一个值,队列没有值时直接报错
18 full() 判断队列是否满了
19 empty() 判断队列是否为空
20 qsize() 返回队列实际的长度(存了多少个值)
21
22 '''
23
24 import queue
25
26 class Human(object):
27 def __init__(self,n):
28 self.n = n
29
30 print('\033[31;1m 先进先出队列Queue \033[0m')
31 q = queue.Queue(maxsize=3) #队列中最多存储几个值,可以不加maxsize
32 # q.get() #get是阻塞函数,当队列里面没有数据时,就会一直等待
33 # q.get(timeout=3) # 阻塞3秒,没有数据就报错
34 # q.get_nowait() #不阻塞,没有数据就直接报错 queue.Empty Error
35 q.put([1,2,'a',[5,6]]) #这里传入的列表在队列中只是一个数据
36 q.put(1)
37
38 h = Human(2)
39 q.put(h)
40 print(q.full()) # full 判断队列是否存满了 empty 判断队列是否为空
41 # q.put(4,timeout=2)
42
43 print('\033[31;1m 先进后出队列LifoQueue \033[0m')
44
45 lq = queue.LifoQueue()
46 for i in range(5):
47 lq.put(i)
48 print('LifoQueue values:',lq) #LifoQueue values: <queue.LifoQueue object at 0x0000022EA3959DA0>
49 print('取第一个值:',lq.get())
50
51 print('\033[31;1m 设置优先级队列PriorityQueue \033[0m')
52 pq = queue.PriorityQueue()
53 pq.put((1,'asb'))
54 pq.put((10,223)) #优先级和数据以元组两个值的形式传递给put,因为put第二个参数默认是timeout
55 pq.put((8,[1,5]))
56 pq.put((3,(1,'c')))
57
58 print(pq.get())
59 print(pq.get())
60 print(pq.get())
61 print(pq.get())
62 '''
63 (1, 'asb')
64 (3, (1, 'c'))
65 (8, [1, 5])
66 (10, 223)
67 '''
执行结果
先进先出队列Queue
True
先进后出队列LifoQueue
LifoQueue values: <queue.LifoQueue object at 0x000001C9D6CE3CC0>
取第一个值: 4
设置优先级队列PriorityQueue
(1, 'asb')
(3, (1, 'c'))
(8, [1, 5])
(10, 223)
2、queue简单使用
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 import queue
5 import threading
6 import time
7
8 def get_value(i,q):
9 time.sleep(2)
10 value = q.get()
11 print('线程[%s]获取的值:%s' %(i,value))
12
13 if __name__ == '__main__':
14 q = queue.Queue()
15 for i in range(20):
16 q.put(i**2)
17
18 thread_list = []
19 for i in range(20):
20 t = threading.Thread(target=get_value,args=[i,q,])
21 t.start()
22 thread_list.append(t)
23
24 for i in thread_list:
25 i.join()
26
27 print('\033[32;1m ----main thread end----\033[0m')
执行结果
线程[3]获取的值:0
线程[2]获取的值:1
线程[1]获取的值:4
线程[0]获取的值:9
线程[18]获取的值:16
线程[19]获取的值:25
线程[17]获取的值:36
线程[10]获取的值:49
线程[15]获取的值:64
线程[14]获取的值:81
线程[12]获取的值:100
线程[16]获取的值:121
线程[11]获取的值:144
线程[9]获取的值:169
线程[8]获取的值:196
线程[7]获取的值:225
线程[5]获取的值:256
线程[13]获取的值:289
线程[6]获取的值:324
线程[4]获取的值:361
----main thread end----
3、基于queue的生产者消费者模型
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 import threading
5 import queue
6 import time
7
8 def customer(n):
9 while True:
10 # print('hello')
11 print("\033[32;1m customer [%s] \033[0m get task: %s" % (n,q.get()))
12 #消费者线程第一次执行到get时会阻塞,所以每次都是生产者在前面
13 time.sleep(1)
14 q.task_done() #每个从队列里面取值的线程执行结束后,都会通知队列说任务结束
15
16 def producer(n):
17 count = 1
18 while True:
19 print("producer [%s] producted a new task: %s " %(n,count))
20 q.put(count)
21 count += 1
22 q.join() #当队列里面还有值就处于阻塞状态,没值时就会解除阻塞(阻塞状态是不占用任何资源的)
23 print('all task has benn cosumed by consumers...')
24
25
26 if __name__ == '__main__':
27 q = queue.Queue()
28 thread_list = [] #用来存放所有的线程,目的是后面的join,让父线程等这些线程结束后再结束
29
30 for i in range(3):
31 c = threading.Thread(target=customer,args=[i,])
32 c.start()
33 thread_list.append(c)
34
35 for i in range(2):
36 p = threading.Thread(target=producer,args=[i,])
37 p.start()
38 thread_list.append(p)
39
40 for thread in thread_list:
41 thread.join()
42
43
44 # print("\033[32;1m ----main thread end---- \033[0m")
执行结果
producer [0] producted a new task: 1
customer [0] get task: 1
producer [1] producted a new task: 1
customer [1] get task: 1
all task has benn cosumed by consumers...
all task has benn cosumed by consumers...
producer [0] producted a new task: 2
producer [1] producted a new task: 2
customer [2] get task: 2
customer [1] get task: 2
all task has benn cosumed by consumers...
all task has benn cosumed by consumers...
producer [0] producted a new task: 3
producer [1] producted a new task: 3
customer [0] get task: 3
customer [1] get task: 3
all task has benn cosumed by consumers...
producer [0] producted a new task: 4
customer [2] get task: 4
all task has benn cosumed by consumers...
all task has benn cosumed by consumers...
producer [0] producted a new task: 5
producer [1] producted a new task: 4
customer [0] get task: 4
customer [1] get task: 5