zoukankan      html  css  js  c++  java
  • 多线程必备技能

    前期

    1. Queue模块提供了同步线程安全的队列类,包括:
      FIFO (先入先出)队列 Queue
      LIFO (后入先出)队列 LifoQueue
      优先队列 PriorityQueue
      这些队列都提供了锁,可以直接使用队列来实现线程间的同步
    2. 反正就是给我这种小白写多线程中直接使用就好了

    Queue 常用模块

    queue.Queue(maxsize=0)				# FIFO, 如果maxsize小于1就表示队列长度无限
    queue.LifoQueue(maxsize=0)			# LIFO, 如果maxsize小于1就表示队列长度无限
    queue.qsize()						# 返回队列的大小
    queue.empty()						# 如果队列为空,返回True,反之False
    queue.full()						# 如果队列满了,返回True,反之False,Queue.full 与 maxsize 大小对应
    queue.put(item, [block[, timeout]])	# 写队列,timeout等待时间 
    queue.get([block[, timeout]])		# 获取队列,timeout等待时间
    queue.get_nowait()					# 相当于Queue.get(False),非阻塞方法
    queue.queue.clear()					# 清空队列
    queue.join()     					# 阻塞调用线程,直到队列中的所有任务被处理掉
    queue.task_done()					# 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
    									# 每个get()调用得到一个任务,接下来task_done()调用告诉队列该任务已经处理完毕。
    

    queue 写入与读取

    # !/usr/bin/env python
    # -*- coding: utf-8 -*-
    # @Date    : 2020/4/22 9:54
    # @File    : Queue.py
    # @Link    : https://www.cnblogs.com/BenLam/
    
    from queue import Queue
    from queue import LifoQueue
    
    def test():
        q = Queue()
        for i in range(6):
            q.put(i)
    
        while not q.empty():
            print(q.get())
    test()
    
    """
    打印:
        0
        1
        2
        3
        4
        5
    """
    
    def test():
        q = LifoQueue()
        for i in range(6):
            q.put(i)
    
        while not q.empty():
            print(q.get())
    test()
    
    """
    打印:
        5
        4
        3
        2
        1
        0
    """
    

    Queue 例子

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # @Date    : 2020/4/22 9:54
    # @File    : Queue_test.py
    # @Author  : BenLam
    # @Link    : https://www.cnblogs.com/BenLam/
    # @Version : PyCharm
    
    from queue import Queue,LifoQueue,PriorityQueue
    from queue import deque
    
    #先进先出队列
    q = Queue(maxsize=10)
    
    #后进先出队列
    lq = LifoQueue(maxsize=11)
    
    #优先级队列
    pq = PriorityQueue(maxsize=10)
    
    for _ in range(10):
        q.put(_)
        lq.put(_)
        pq.put(_)
    
    print("先进先出队列: %s ;是否为空: %s ;多大, %s ;是否满, %s" %(q.queue,q.empty(),q.qsize(),q.full()))
    print("后进先出队列: %s ;是否为空: %s ;多大, %s ;是否满, %s" %(lq.queue,lq.empty(),lq.qsize(),lq.full()))
    print("优先级队列:  %s ;是否为空: %s ,多大, %s ;是否满, %s " %(pq.queue,pq.empty(),pq.qsize(),pq.full()))
    
    print(f" q: {q.get()} 
    lq: {lq.get()} 
    pq: {pq.get()}")
    
    print("先进先出队列: %s ;是否为空: %s ;多大, %s ;是否满, %s" %(q.queue,q.empty(),q.qsize(),q.full()))
    print("后进先出队列: %s ;是否为空: %s ;多大, %s ;是否满, %s" %(lq.queue,lq.empty(),lq.qsize(),lq.full()))
    print("优先级队列: %s ;是否为空: %s ,多大, %s ;是否满, %s" %(pq.queue,pq.empty(),pq.qsize(),pq.full()))
    
    # === === === === === === === === === === === ===
    print("=== === 双端队列 === ===")
    dq=deque(['1','2'])
    print(dq)
    dq.append('c')
    print(dq)
    print(dq.pop())
    print(dq)
    print(dq.popleft())
    print(dq)
    dq.appendleft('d')
    print(dq)
    print(len(dq))
    print("=== === 双端队列 结束 === ===")
    """
    打印:
        先进先出队列: deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) ;是否为空: False ;多大, 10 ;是否满, True
        后进先出队列: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ;是否为空: False ;多大, 10 ;是否满, False
        优先级队列:  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ;是否为空: False ,多大, 10 ;是否满, True
             q: 0
            lq: 9
            pq: 0
        先进先出队列: deque([1, 2, 3, 4, 5, 6, 7, 8, 9]) ;是否为空: False ;多大, 9 ;是否满, False
        后进先出队列: [0, 1, 2, 3, 4, 5, 6, 7, 8] ;是否为空: False ;多大, 9 ;是否满, False
        优先级队列: [1, 3, 2, 7, 4, 5, 6, 9, 8] ;是否为空: False ,多大, 9 ;是否满, False
        === === 双端队列 === ===
            deque(['1', '2'])
            deque(['1', '2', 'c'])
                c
            deque(['1', '2'])
                1
            deque(['2'])
            deque(['d', '2'])
                2
        === === 双端队列 结束 === ===
        [Finished in 0.6s]
    """
    

    生产消费者

    • 生产消费者就是 → 生产者/消费者模式,反正我们就叫它为:生肖(生消)
    • 生消并非 GOF 自带模式,不知道 GOF 可以参考我另一篇笔记《2020年 - 在家学习汇总》
    • | 【 生产者 】 → → → [ 缓冲区 ] → → → 【 消费者 】
    • 生产者 - 负责产生数据,放入缓冲区
    • 消费者 - 负责缓冲区取值并处理
    • 优点:
      • 解耦
        1. 缓冲区的存在可以让他俩降低互相之间的依赖性,老产修改代码不影响老消
      • 并发
        1. 他俩不是直接调用,而是两个独立的个体,可以说老产把数据摊牌在缓冲区完事了;
        2. 老消又不用跪着向想他要饭,直接从缓冲区取数据就好了;
        3. 参考(饭堂阿姨把饭菜+饭勺放在桌上,再也不怕阿姨帕金森模式)

    生消例子

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # @Date    : 2020/4/22 9:54
    # @File    : PC_test.py
    # @Author  : BenLam
    # @Link    : https://www.cnblogs.com/BenLam/
    # @Version : PyCharm
    
    import queue
    import threading
    
    def Produce(name):
        count = 0
        while count < 5:
            count += 1
            print(f"{name} 已经做好了第 {count} 双皮鞋, - 皮鞋搞完,把妹去")
            q.put(count)
            q.join()  # 等待接收信号
    
    def Consumer(name):
        count = 0
        while count < 5:
            data = q.get()
            # print(f"{name} 即将囤货......")
            q.task_done()
            print(f"{name} 已经把 {data} 双皮鞋买了...")
            count += 1
    
    if __name__ == '__main__':
        q = queue.Queue()
        A = threading.Thread(target=Produce, args=("皮革厂老板 - ",))
        B = threading.Thread(target=Consumer, args=("A - ",))
        C = threading.Thread(target=Consumer, args=("B - ",))
        D = threading.Thread(target=Consumer, args=("C - ",))
    
        A.setDaemon(True)
        A.start()
        B.start()
        C.start()
        D.start()
    
    """
    打印:
        皮革厂老板 -  已经做好了第 1 双皮鞋, - 皮鞋搞完,把妹去
        A -  已经把 1 双皮鞋买了...
        皮革厂老板 -  已经做好了第 2 双皮鞋, - 皮鞋搞完,把妹去
        B -  已经把 2 双皮鞋买了...
        皮革厂老板 -  已经做好了第 3 双皮鞋, - 皮鞋搞完,把妹去
        皮革厂老板 -  已经做好了第 4 双皮鞋, - 皮鞋搞完,把妹去
        C -  已经把 3 双皮鞋买了...
        A -  已经把 4 双皮鞋买了...
        皮革厂老板 -  已经做好了第 5 双皮鞋, - 皮鞋搞完,把妹去
        B -  已经把 5 双皮鞋买了...
    [Cancelled]
    """
    
  • 相关阅读:
    素数路径Prime Path POJ3126 素数,BFS
    Fliptile POJ3279 DFS
    Find the Multiple POJ1426
    洗牌Shuffle'm Up POJ3087 模拟
    棋盘问题 POJ1321 DFS
    抓住那只牛!Catch That Cow POJ3278 BFS
    Dungeon Master POJ2251 三维BFS
    Splitting into digits CodeForce#1104A
    Ubuntu下手动安装Nvidia显卡驱动
    最大连续子序列和
  • 原文地址:https://www.cnblogs.com/BenLam/p/12752389.html
Copyright © 2011-2022 走看看