zoukankan      html  css  js  c++  java
  • 多线程-同步对象 队列 生产者消费者模式

    多线程

    同步对象

    解决什么问题?

    想要指定的一个线程先执行,再去执行其他线程

    精华如下

    #event = threading.Event()
    # event.isSet():返回event的状态值;
    #
    # event.wait():如果 event.isSet()==False将阻塞线程;
    #
    # event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度;
    #
    # event.clear():恢复event的状态值为False。
    
    import threading
    import time
    
    ll=[]
    
    class Boss(threading.Thread):
        def run(self):
            print("老板说今天23:00下班")
            print(event.is_set())
            time.sleep(1)
            event.set()
            time.sleep(6)
            print("老板说时间到了下班")
            event.set()
    
    class Worker(threading.Thread):
        def run(self):
            event.wait()
            print("员工说:不要加班啊!!")
            event.clear()
            event.wait()
            print("员工说:下班下班!")
    
    if __name__ == '__main__':
        event = threading.Event()
        boss=Boss()
        ll.append(boss)
        for i in range(5):
            i=Worker()
            ll.append(i)
        for z in ll:
            z.start()
    

    信号量

    相当于一次可以多个线程的同步锁

    输出结果:一次打印5个线程的输出

    import threading
    import time
    
    class zx(threading.Thread):
        def run(self):
            semaphore.acquire()
            time.sleep(3)
            print(self.name)
            semaphore.release()
    
    if __name__ == '__main__':
        thr=[]
        semaphore=threading.Semaphore(5)
        for i in range(100):
            i=zx()
            i.start()
    

    Thread-1
    Thread-4
    Thread-2
    Thread-3
    Thread-5
    Thread-6
    Thread-9
    Thread-7
    Thread-8
    Thread-10

    ....

    队列queue

    list是线程不安全的

    queue是线程安全的

    可以让多个线程存取数据,不会出现问题

    队列常用方法

    Queue.task_done():队列计数器-1

    Queue.join(): block直到queue被消费完毕

    队列有三种存取方式

    1.先进先出

    import queue
    
    q=queue.Queue()
    q.put("sad")
    q.put("123")
    q.put("sady7854")
    
    while 1:
        print(q.get())
    

    sad
    123
    sady7854

    2.先进后出

    import queue
    
    q=queue.LifoQueue()
    q.put("sad")
    q.put("123")
    q.put("sady7854")
    
    while 1:
        print(q.get())
    
    sady7854
    123
    sad
    

    3.按优先级

    import queue
    
    q=queue.PriorityQueue()
    #注意这里用的是元组
    q.put((3,"sad"))
    q.put((1,"123"))
    q.put((2,"sady7854"))
    
    while 1:
        print(q.get())
    
    (1, '123')
    (2, 'sady7854')
    (3, 'sad')
    

    当数据插入,队列满了,他就会等待,取出一个在存入,默认不报错,可以设置报错

    取数据时,当数据没有了,他会等待一个存入,再取出,默认也不报错

    生产者消费者模型(队列)

    生产者:生产数据的任务

    消费者:处理数据的任务

    举个例子:包子生产出来放在,货架上,有顾客来了,就买走。货架就相当于队列

    代码实现了一个简单的例子,并不完善,用于理解

    提高生产者生产的效率和消费者消费的效率

    import queue
    import threading
    import random
    import time
    
    def producer(name):
        while 1:
            print(f"{name}正在制作包子")
            t=random.randint(1,4)
            time.sleep(t)
            bao_zi_que.put("包子")
            print("新出炉的包子哟!")
            bao_zi_que.task_done()#通知join有内容了,不用等待了
            time.sleep(0.5)
    
    def customer(name):
        while 1:
            print(f"{name}在等待包子")
            bao_zi_que.join()
            bao_zi_que.get()
            time.sleep(1)
            print(f"{name}吃掉了包子")
    
    bao_zi_que=queue.Queue()
    
    if __name__ == '__main__':
        print("欢迎来到源氏百年包子店")
        A=threading.Thread(target=producer,args=("包子老板",))
        B=threading.Thread(target=customer,args=("zx",))
        C=threading.Thread(target=customer,args=("wl",))
        D=threading.Thread(target=customer,args=("125",))
        A.start()
        B.start()
        C.start()
        D.start()
    

    欢迎来到源氏百年包子店
    包子老板正在制作包子
    zx在等待包子
    wl在等待包子
    125在等待包子
    新出炉的包子哟!
    包子老板正在制作包子
    zx吃掉了包子
    zx在等待包子
    新出炉的包子哟!
    包子老板正在制作包子
    wl吃掉了包子
    wl在等待包子
    新出炉的包子哟!
    包子老板正在制作包子
    125吃掉了包子
    125在等待包子
    新出炉的包子哟!
    包子老板正在制作包子
    zx吃掉了包子
    zx在等待包子
    新出炉的包子哟!
    包子老板正在制作包子
    wl吃掉了包子
    wl在等待包子
    新出炉的包子哟!
    包子老板正在制作包子

  • 相关阅读:
    设计模式总结——程序猿武功秘籍(下一个)
    easyui datagrid显示进度条控制操作
    使用CountDownLatch和CyclicBarrier处理并发线程
    人类探索地外文明显著取得的进展
    Linux 启动过程的详细解释
    不会跳回到微博认定申请书
    unix域套接字UDP网络编程
    VS SQL 出现%CommonDir%dte80a.olb 该解决方案
    数据仓库与数据挖掘的一些基本概念
    CheckBoxPreference组件
  • 原文地址:https://www.cnblogs.com/zx125/p/11443719.html
Copyright © 2011-2022 走看看