python --- queue模块使用

简介: 1. 什么是队列?  学过数据结构的人都知道,如果不知道队列,请Google(或百度)。2. 在python中什么是多生产者,多消费模型?  简单来说,就是一边生产(多个生产者),一边消费(多个消费者)。

1. 什么是队列?

  学过数据结构的人都知道,如果不知道队列,请Google(或百度)。

2. 在python中什么是多生产者,多消费模型?

  简单来说,就是一边生产(多个生产者),一边消费(多个消费者)。比如,一边有m个线程生产数据,另一边有n个线程消费(使用)数据,这就是多生产者,多消费者模型。

  注:消费依赖生产(没有厂家生产产品,就不会有关于这种产品的消费),在python中,如果生产者线程没有产生数据,那么消费者线程有关于消费行为的操作就应当处于阻塞状态。

3. 在python中为什么有queue这个标准模块?它有什么用?

  用threading.Lock Objects或其他的锁来完成上一问的需求会很复杂,所以queue这个模块简化了这些操作。

  queue模块实现多生产者,多消费者队列。它特别适用于信息必须在多个线程间安全地交换的多线程程序中。该模块中的Queue类实现了所有需要的锁定语义。

  queue模块实现了三类队列,主要差别在于取得数据的顺序上。在FIFO(First In First Out,先进先出)队列中,最早加入的任务会被最先得到。在LIFO(Last In First Out,后进先出)队列中,最后加入的任务会被最先得到(就像栈一样)。在优先队列中,任务被保持有序(使用heapq模块),拥有最小值的任务(优先级最高)被最先得到。

 

queue模块提供的方法:

 1 Queue.empty()
 2 """
 3 如果队列为空,返回True,否则返回False。如果empty()返回True,它不保证后续调用put()不会阻塞。类似的,如果empty()返回False也不能保证接下来的get()调用不会被阻塞。
 4 """
 5 
 6 Queue.full()
 7 """
 8 如果队列已满,则返回True,否则返回False。如果full()返回True,它不保证后续调用get()不会阻塞。类似的,如果full()返回False并不能保证接下来的put()调用不会被阻塞。
 9 """
10 
11 Queue.qsize()
12 """
13 返回队列的近似大小。注意,qsize()> 0不保证随后的get()不会阻塞,qsize() < maxsize也不会保证put()不会被阻塞。
14 """
15 
16 Queue.put(item, block=True, timeout=None)
17 """
18 将item放入队列中。如果可选的参数block为True且timeout为None(默认的情况,阻塞调用,无超时),如有必要(比如队列满),阻塞调用线程,直到有空闲槽可用。如果超时是正数,则它最多阻塞超时秒,如果在该时间内没有空闲插槽,则引发Full异常。如果block为False,如果有空闲槽可用将数据放入队列,否则立即抛出Full异常(非阻塞调用,timeout被忽略)。
19 """
20 
21 Queue.get(block=True, timeout=None)
22 """
23 从队列中移除并返回一个数据。如果可选的参数block为True且timeout为None(默认的情况,阻塞调用,无超时),阻塞调用进程直到有数据可用。如果超时是正数,则它最多阻塞超时秒,如果在该时间内没有可用的项,则引发Empty异常。如果block为False,如果有数据可用返回数据,否则立即抛出Empty异常(非阻塞调用,timeout被忽略)。
24 """
25 
26 Queue.put_nowait(item)
27 """
28 等同于put(item, block=False)(非阻塞调用)。
29 """
30 
31 Queue.get_nowait()
32 """
33 等同于get(block=False)(非阻塞调用)。
34 """
35 
36 Queue.task_done()
37 """
38 意味着之前入队的一个任务已经完成。由队列的消费者线程调用。每一个get()调用得到一个任务,接下来的task_done()调用告诉队列该任务已经处理完毕。
39 
40 If a join() is currently blocking, it will resume when all items have been processed (meaning that a task_done() call was received for every item that had been put() into the queue).
41 
42 如果该方法被调用的次数多于被放入队列中的任务的个数,ValueError异常会被抛出。
43 """
44 
45 Queue.join()
46 """
47 阻塞调用线程,直到队列中的所有任务被处理掉。
48 
49 只要有数据被加入队列,未完成的任务数就会增加。当消费者线程调用task_done()以指示该项目已检索并且其上的所有工作都已完成时,计数将减少。当未完成的任务数降到0,join()解除阻塞。
50 """
Queue对象(Queue、LifoQueue和PriorityQueue)提供了下述的公共方法

   注:由于同一进程的线程之间内存空间是共享的,故在同一进程的任一线程中定义的Queue对象,在该进程的任一线程都可以使用。

例(演示queue模块的使用):

 1 import queue,threading
 2 import random,time
 3 
 4 class Producter(threading.Thread):
 5     def __init__(self, name):
 6         super(Producter, self).__init__()
 7         self.name = "Producter:" + str(name)
 8 
 9     def run(self):
10         things = ['A', 'B', 'C']
11         for i in range(3):
12             production = random.choice(things)
13             print(self.name + " producted--->" + production)
14             production = production + " from " + self.name
15             all_productions.put(production) #将生产的数据放入队列
16             time.sleep(1)
17         time.sleep(5)
18 
19 class Consumer(threading.Thread):
20     def __init__(self, name):
21         super(Consumer, self).__init__()
22         self.name = "Consumer:" + str(name)
23 
24     def run(self):
25         for i in range(2):
26             thing = all_productions.get()  #拿出已经生产好的数据
27             print(self.name + " is using--->" + thing)
28             time.sleep(2)
29             all_productions.task_done()   #告诉队列有关这个数据的任务已经完成
30         time.sleep(5)
31 
32 if __name__ == "__main__":
33     all_productions = queue.Queue()
34 
35     #启动两个生产者线程生
36     p_s = []
37     for i in range(2):
38         p = Producter(i)
39         p.start()
40         p_s.append(p)
41 
42     #启动三个消费者线程消费
43     c_s = []
44     for i in range(3):
45         c = Consumer(i)
46         c.start()
47         c_s.append(c)
48 
49     #阻塞,直到生产者生产的数据被消耗完
50     all_productions.join()
51     #等待生产者线程结束
52     for p in p_s:
53         p.join()
54     #等待消费者线程结束
55     for c in c_s:
56         c.join()
57     print("finish....")
queue模块简单使用演示

 

目录
相关文章
|
1月前
|
开发者 Python
如何在Python中管理模块和包的依赖关系?
在实际开发中,通常会结合多种方法来管理模块和包的依赖关系,以确保项目的顺利进行和可维护性。同时,要及时更新和解决依赖冲突等问题,以保证代码的稳定性和可靠性
50 4
|
12天前
|
Python
Python Internet 模块
Python Internet 模块。
107 74
|
1月前
|
算法 数据安全/隐私保护 开发者
马特赛特旋转算法:Python的随机模块背后的力量
马特赛特旋转算法是Python `random`模块的核心,由松本真和西村拓士于1997年提出。它基于线性反馈移位寄存器,具有超长周期和高维均匀性,适用于模拟、密码学等领域。Python中通过设置种子值初始化状态数组,经状态更新和输出提取生成随机数,代码简单高效。
108 63
|
1月前
|
测试技术 Python
手动解决Python模块和包依赖冲突的具体步骤是什么?
需要注意的是,手动解决依赖冲突可能需要一定的时间和经验,并且需要谨慎操作,避免引入新的问题。在实际操作中,还可以结合使用其他方法,如虚拟环境等,来更好地管理和解决依赖冲突😉。
|
1月前
|
持续交付 Python
如何在Python中自动解决模块和包的依赖冲突?
完全自动解决所有依赖冲突可能并不总是可行,特别是在复杂的项目中。有时候仍然需要人工干预和判断。自动解决的方法主要是提供辅助和便捷,但不能完全替代人工的分析和决策😉。
|
1月前
|
JSON Linux 数据格式
Python模块:从入门到精通,只需一篇文章!
Python中的模块是将相关代码组织在一起的单元,便于重用和维护。模块可以是Python文件或C/C++扩展,Python标准库中包含大量模块,如os、sys、time等,用于执行各种任务。定义模块只需创建.py文件并编写代码,导入模块使用import语句。此外,Python还支持自定义模块和包,以及虚拟环境来管理项目依赖。
Python模块:从入门到精通,只需一篇文章!
|
1月前
|
Python
Python的模块和包
总之,模块和包是 Python 编程中非常重要的概念,掌握它们可以帮助我们更好地组织和管理代码,提高开发效率和代码质量
41 5
|
1月前
|
数据可视化 Python
如何在Python中解决模块和包的依赖冲突?
解决模块和包的依赖冲突需要综合运用多种方法,并且需要团队成员的共同努力和协作。通过合理的管理和解决冲突,可以提高项目的稳定性和可扩展性
|
1月前
|
Python
在Python中,可以使用内置的`re`模块来处理正则表达式
在Python中,可以使用内置的`re`模块来处理正则表达式
55 5
|
1月前
|
Java 程序员 开发者
Python的gc模块
Python的gc模块