首页 > 技术文章 > Python之队列

george92 2018-07-30 10:33 原文

Python之队列

  队列:先进先出

    队列与线程有关。

    在多线程编程时,会起到作用。

    作用:确保信息安全的进行交换。

    有get 和 put 方法。

'''

创建一个“队列”对象

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

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

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

'''

 

  1 import queue
  2 
  3 #q=queue.Queue(3)  # 默认是  先进先出(FIFO)
  4 
  5 # q.put(111)
  6 # q.put("hello")
  7 # q.put(222)
  8 #
  9 # q.put(223,False)
 10 #
 11 # print(q.get())
 12 # # print(q.get())
 13 # # print(q.get())
 14 # #
 15 # q.get(False)
 16 
 17 
 18 # queue 优点: 线程安全的
 19 
 20 
 21 
 22 # join和task_done
 23 
 24 
 25 # q=queue.Queue(5)
 26 
 27 # q.put(111)
 28 # q.put(222)
 29 # q.put(22222)
 30 #
 31 #
 32 # while not q.empty():
 33 #         a=q.get()
 34 #         print(a)
 35 #q.task_done()
 36 
 37 
 38 # b=q.get()
 39 # print(b)
 40 # q.task_done()
 41 
 42 # q.join()
 43 #
 44 # print("ending")
 45 
 46 
 47 #  先进后出模式
 48 
 49 # q=queue.LifoQueue()  #  Lifo  last in first out
 50 #
 51 #
 52 # q.put(111)
 53 # q.put(222)
 54 # q.put(333)
 55 #
 56 # print(q.get())
 57 
 58 
 59 
 60 # 优先级
 61 
 62 # q=queue.PriorityQueue()
 63 #
 64 # q.put([4,"hello4"])
 65 # q.put([1,"hello"])
 66 # q.put([2,"hello2"])
 67 #
 68 # print(q.get())
 69 # print(q.get())
 70 
 71 
 72 
 73 # import queue
 74 #
 75 #
 76 # q=queue.Queue()
 77 #
 78 # q.put(111)
 79 # q.put(2222)
 80 # q.put(22333)
 81 #
 82 # print( )
 83 
 84 
 85 #生产者消费者模型
 86 
 87 import time,random
 88 import queue,threading
 89 
 90 q = queue.Queue()
 91 
 92 def Producer(name):
 93   count = 0
 94   while count <10:
 95     print("making........")
 96     time.sleep(2)
 97     q.put(count)
 98     print('Producer %s has produced %s baozi..' %(name, count))
 99 
100     count +=1
101     #q.task_done()
102     #q.join()
103     print("ok......")
104 
105 def Consumer(name):
106   count = 0
107   while count <10:
108     time.sleep(1)
109     if not q.empty():
110         data = q.get()
111         #q.task_done()
112         #q.join()
113         print(data)
114         print('\033[32;1mConsumer %s has eat %s baozi...\033[0m' %(name, data))
115     else:
116         print("-----no baozi anymore----")
117 
118     count +=1
119 
120 p1 = threading.Thread(target=Producer, args=('A',))
121 c1 = threading.Thread(target=Consumer, args=('B',))
122 
123 # c2 = threading.Thread(target=Consumer, args=('C',))
124 # c3 = threading.Thread(target=Consumer, args=('D',))
125 p1.start()
126 c1.start()
127 # c2.start()
128 # c3.start()
View Code

 

  生产者消费者模型:

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

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

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

 1 import time,random
 2 import queue,threading
 3 
 4 q = queue.Queue()
 5 
 6 def Producer(name):
 7   count = 0
 8   while count <10:
 9     print("making........")
10     time.sleep(random.randrange(3))
11     q.put(count)
12     print('Producer %s has produced %s baozi..' %(name, count))
13     count +=1
14     #q.task_done()
15     #q.join()
16     print("ok......")
17 def Consumer(name):
18   count = 0
19   while count <10:
20     time.sleep(random.randrange(4))
21     if not q.empty():
22         data = q.get()
23         #q.task_done()
24         #q.join()
25         print(data)
26         print('\033[32;1mConsumer %s has eat %s baozi...\033[0m' %(name, data))
27     else:
28         print("-----no baozi anymore----")
29     count +=1
30 
31 p1 = threading.Thread(target=Producer, args=('A',))
32 c1 = threading.Thread(target=Consumer, args=('B',))
33 # c2 = threading.Thread(target=Consumer, args=('C',))
34 # c3 = threading.Thread(target=Consumer, args=('D',))
35 p1.start()
36 c1.start()
37 # c2.start()
38 # c3.start()
View Code

 

进程:最小的资源管理单位(盛放线程的容器)

线程:最小的执行单位


Cpython因为存在GIL导致同一时刻同一进程只能有一个线程被执行。


关于setdaemon:程序直到不存在非守护线程时退出!

 

链接

推荐阅读