zoukankan      html  css  js  c++  java
  • py 的 第 33 天

    1。今天讲了一下线程安全的问题   线程安全的有,列表,字典,队列(队列在后面生产者消费者模型里有)

    2.锁,最普通的锁    lock

    import threading
    import time
    
    v = []
    lock = threading.Lock()
    
    def func(arg):
        lock.acquire()        #这个只能锁一次,如果锁两次及以上就会锁死
        v.append(arg)
        time.sleep(0.01)
        m = v[-1]
        print(arg,m)
        lock.release()     #这个正常解锁一次就OK了,上边锁多了,下面怎么也解不开
    
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    

     3,锁,用的最多的锁 Rlock

    import threading
    import time
    
    v = []
    lock = threading.RLock()
    def func(arg):
        lock.acquire()   #这个可以锁2次       及以上
        lock.acquire()
    
        v.append(arg)
        time.sleep(0.01)
        m = v[-1]
        print(arg,m)
    
        lock.release()#上面锁几次这就解几次
        lock.release()
    
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()                
    

     4,锁,名字最长的锁

    import time
    import threading
    
    lock = threading.BoundedSemaphore(3)  #你这里写多少,他就一次走几个线程
    def func(arg):
        lock.acquire()
        print(arg)
        time.sleep(1)
        lock.release()
    
    
    for i in range(20):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    

     5.锁,

    import time
    import threading
    
    lock = threading.Condition()
    
    # ############## 方式一 ##############
    
    def func(arg):
        print('线程进来了')
        lock.acquire()   #这个锁还是必加的
        lock.wait() # 加锁     这里新加的锁,在多写一个主线程
    
        print(arg)
        time.sleep(1)
    
        lock.release()  #同上
    
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    
    while True:
        inp = int(input('>>>'))    #一次输入多少就执行多少线程
    
        lock.acquire()   #同上
        lock.notify(inp)  #固定写法
        lock.release()   #同上
    
    
    # ############## 方式二 ##############
    """
    def xxxx():
        print('来执行函数了')
        input(">>>")     #这个智能一点,在这里可以等到执行一个with open  等。。。然后才返回值,返回什么还可以再随机
        # ct = threading.current_thread() # 获取当前线程
        # ct.getName()
        return True
    
    def func(arg):
        print('线程进来了')
        lock.wait_for(xxxx)    #一直在等,等某个条件满足了,就往下走
        print(arg)
        time.sleep(1)
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()

    6,锁,

    import time
    import threading
    
    lock = threading.Event()
    
    
    def func(arg):
        print('线程来了')
        lock.wait() # 加锁:红灯
        print(arg)
    
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    
    input(">>>>")
    lock.set() # 绿灯      只要没有绿灯就一直锁死,只要绿灯过一次
    lock.wait()  #只要绿灯过一次,这里再写几个也没用,只有clear有用
    
    lock.clear() # 再次变红灯
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    
    input(">>>>")
    lock.set()
    

     7.  threading.local()

    import time
    import threading
    
    v = threading.local()
    
    def func(arg):
        # 内部会为当前线程创建一个空间用于存储:phone=自己的值
         会为每一个线程储存一个空间
        v.phone = arg
        time.sleep(2)
        print(v.phone,arg) # 去当前线程自己空间取值    这两个值一样
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()    
    

    8.threadinglocal原理 

    import time
    import threading
    
    DATA_DICT = {}
    
    def func(arg):
        ident = threading.get_ident() 获取当前线程ID #c= threading.current_thread()  获取当前线程对象
        DATA_DICT[ident] = arg
        time.sleep(1)
        print(DATA_DICT[ident],arg)
    
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    

     9.threadinglocal为每个线程维护一个空间(字典),用于当前线程存取自己的值,保证线程之间的数据隔离 {线程id:{自己的key:自己的value}}

    import time
    import threading
    INFO = {}
    class Local(object):
    
        def __getattr__(self, item):
            ident = threading.get_ident()
            return INFO[ident][item]
    
        def __setattr__(self, key, value):
            ident = threading.get_ident()
            if ident in INFO:
                INFO[ident][key] = value
            else:
                INFO[ident] = {key:value}
    
    obj = Local()
    
    def func(arg):
        obj.phone = arg # 调用对象的 __setattr__方法(“phone”,1)
        time.sleep(2)
        print(obj.phone,arg)
    
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    
    
    
    每个对象都是调用上面的方法
    def __getitem__(self,item)
    obj['x']
    def __getattr__(self,item)
    obj.x  执行了他就等于执行attr x=item
    def __setattr__(self,key,value):
    obj.x=6    这个key是x value是6
    

     10.小数据池

    from concurrent.futures import ThreadPoolExecutor
    import time
    
    def task(a1,a2):
        time.sleep(2)
        print(a1,a2)
    
    # 创建了一个线程池(最多5个线程)
    pool = ThreadPoolExecutor(5)
    
    for i in range(40):
        # 去线程池中申请一个线程,让线程执行task函数。
        pool.submit(task,i,8)         
    
    
    
    
    for i in range(10):    同比这个来讲的话     下面的对象这个要等于一下,arsg传值,上面的 一个submit就全搞定了
        t =threading.Thread(target=func,args=(i,))
        t.start()
    

     11.生产者消费者模型

    用户是生产者,程序是消费者        生产者把东西放在这里,客户端接收到了就去工作

    解决了一直等待的问题,让客服端和服务端不用直接交互,放在队列里互相等待

  • 相关阅读:
    启智树提高组Day4T3 2的幂拆分
    拉格朗日插值
    #3342. 「NOI2020」制作菜品
    P6776 [NOI2020]超现实树
    P6773 [NOI2020]命运
    P5298 [PKUWC2018]Minimax
    每日总结5.20
    每日总结5.19
    每日总结5.18
    每日总结5.17
  • 原文地址:https://www.cnblogs.com/Mrszhao/p/9641507.html
Copyright © 2011-2022 走看看