• python


    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('33[31;1m 先进先出队列Queue 33[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('33[31;1m 先进后出队列LifoQueue 33[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('33[31;1m 设置优先级队列PriorityQueue 33[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('33[32;1m ----main thread end----33[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("33[32;1m customer [%s] 33[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("33[32;1m ----main thread end---- 33[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
  • 相关阅读:
    js 正则验证输入框只允许输入正实数和正整数和负整数
    阿里maven镜像服务器配置
    JDK环境变量配置
    AndroidStudio OpenCv的配置,不用安装opencv manager
    Java实现红黑树
    基于红黑树的骨架提取Java
    基于Mat变换的骨架提取Java
    Java实现二叉树的四种遍历
    Java实现常见的几种排序
    hough变换检测直线Java
  • 原文地址:https://www.cnblogs.com/xtsec/p/6985763.html
Copyright © 2020-2023  润新知