• 队列Queue


    Python中队列实现了线程安全,即在多线程对同一个队列进行操作时候,线程会独占资源直到这个线程释放,在线程独占资源这个过程中其他线程无法对该队列进行操作。

    queue

    form queue import Queue
    
    q = Queue()             #  实例化一个队列,q = Queue(size=None)
    
    q.put(3)                # 放入一个元素
    elem = q.get()          # 取出一个元素
    
    print(q.empty(), q.qsize)   # 显示是否为空 和 当前元素个数
    # 当queue中的元素满了再进行put操作,或者queue中元素为空时进行get操作时,程序会一直阻塞。
    elem = q.get()    # 此时程序会一直阻塞。可以设置等待时间
    
    elem = q.get(block=True, timeout=10)  # 阻塞10秒,拿到数据继续执行,拿不到数据报错。

    block 参数指定该次取值是阻塞的,设置为False表示不阻塞,没有数据直接报错,也可以使用q. get_nowait(),默认调用get(block=False)

    queue中提供了常用的方法如下

    __init__(maxsize:int)
     _init(maxsize)
     empty()
     full()
     get(block, timeout)
     get_nowait()
     put(item, block, timeout)
     put_nowait(item)
     qsize()
     join()
     task_done()

    PriortyQueue(优先队列)

    优先队列和queue有些许的差别。它的底层使用堆数据结构来进行处理。

    优先队列顾名思义可以根据消息的等级实现消息选择性的弹出,每次取出的值为所有数据中优先级最高的那个数据,也就会这个堆的堆顶元素

    from queue import PriorityQueue
    
    q = PriorityQueue()
    
    q.put(10)
    q.put(5)
    q.put(9)
    
    while not q.empty():
        print(q.get(), end=",")
    
    ====输出结果=====
    5,9,10

    默认每次将“值”最小的元素优先返回,注意:堆中的第一个元素输出后,将最后一个元素置顶,再进行堆调整(queue和LIFOqueue不需要),调整的过程中涉及两个元素之间的大小比较,所以这些数据的数据类型必须可以两两大小比较。否则将会报错。

     queue的线程安全误区

    上面的代码在单线程中是安全的,但是在线程中使用会出现问题,问题在于

    while not q.empty:
        q.get()          # 当只剩下最后一个元素,多个线程同时通过了not empty判断并未取值,然后在取值的时候,未必还有元素,此时线程就阻塞了。
     

    文章一开始说的线程安全是指,在一次操作queue时,保证了只有一条线程操作。比如get,put,qsize,empty等单次操作。模块内部会使用锁的机制来保证线程安全,进入前加锁,操作结束时解锁。

  • 相关阅读:
    ATS(App Transport Security)对HTTP协议屏蔽引起的问题
    后台子线程(非主线程)更新UI引起的警告
    Xcode无法启动ios模拟器的问题
    UIButton修改文字大小问题
    imageNamed和imageWithContentsOfFile-无法加载图片的问题
    storyboard在ios模拟器无法显示的问题
    返回一个数组的连续子数组和的最大值
    第二周学习进度总结
    软件工程开学第一节课课堂测试
    第一周学习进度总结
  • 原文地址:https://www.cnblogs.com/k5210202/p/13067979.html
Copyright © 2020-2023  润新知