时间:2019-12-13
本文章向大家介绍锁,主要包括锁使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

死锁现象与递归锁

  1. 死锁:

    • 是指两个或两个以上的进程或线程在执行过程中,因为争夺资源而造成的一种互相等待的现象,若无外力作用,他们都将无法推进下去,此时系统处于死锁状态或系统产生了死锁,这些永远在等待的进程称为死锁进程

    • 死锁-------------------
      from  threading import Thread,Lock,RLock
      import time
      mutexA = Lock()
      mutexB = Lock()
      class MyThread(Thread):
          def run(self):
              self.f1()
              self.f2()
          def f1(self):
              mutexA.acquire()
              print('\033[33m%s 拿到A锁 '%self.name)
              mutexB.acquire()
              print('\033[45%s 拿到B锁 '%self.name)
              mutexB.release()
              mutexA.release()
          def f2(self):
              mutexB.acquire()
              print('\033[33%s 拿到B锁 ' % self.name)
              time.sleep(1)  #睡一秒就是为了保证A锁已经被别人那到了
              mutexA.acquire()
              print('\033[45m%s 拿到B锁 ' % self.name)
              mutexA.release()
              mutexB.release()
      if __name__ == '__main__':
          for i in range(10):
              t = MyThread()
              t.start() #一开启就会去调用run方法
      
      死锁现象
  2. 递归锁

    1. 解决死锁现象的方法:就是递归锁

    2. 同一把锁,引用一次计数加一,释放一次计数减一,只要计数不为零,其他线程或进程就抢不到,解决死锁问题

    3. 递归锁:在python中,为了支持在同一线程中多次请求同一资源,python提供了可重入锁RLock

    4. 这个RLock内部维持着一个Lock和一个counter变量,counter记录了acquire的次数,从而使资源可以被多次require

    5. 直到一个线程上所有的acquire都被release,其他的线程才能获得资源,

    6. # 2.解决死锁的方法--------------递归锁
      from  threading import Thread,Lock,RLock
      import time
      mutexB = mutexA = RLock()
      class MyThread(Thread):
          def run(self):
              self.f1()
              self.f2()
          def f1(self):
              mutexA.acquire()
              print('\033[33m%s 拿到A锁 '%self.name)
              mutexB.acquire()
              print('\033[45%s 拿到B锁 '%self.name)
              mutexB.release()
              mutexA.release()
          def f2(self):
              mutexB.acquire()
              print('\033[33%s 拿到B锁 ' % self.name)
              time.sleep(1)  #睡一秒就是为了保证A锁已经被别人拿到了
              mutexA.acquire()
              print('\033[45m%s 拿到B锁 ' % self.name)
              mutexA.release()
              mutexB.release()
      if __name__ == '__main__':
          for i in range(10):
              t = MyThread()
              t.start() #一开启就会去调用run方法
      

    解决死锁

    
    
    7. 语法
    

    mutexA=mutexB=threading.RLock() ``#一个线程拿到锁,counter加1,该线程内又碰到加锁的情况,
    则counter继续加1,这期间所有其他线程都只能等待,等待该线程释放所有锁,即counter递减到0为止

8,互斥锁

9,信号量

  1. Semaphore管理一个内置的计数器,计数来控制并发数量

  2. 信号量:信号量是产生一堆的进程|线程,即产生了多个任务去抢那一把锁

  3. from threading import Thread,Semaphore,currentThread
    import time,random
    sm = Semaphore(5) #运行的时候有5个人
    def task():
        sm.acquire()
        print('\033[42m %s上厕所'%currentThread().getName())
        time.sleep(random.randint(1,3))
        print('\033[31m %s上完厕所走了'%currentThread().getName())
        sm.release()
    if __name__ == '__main__':
        for i in range10):  #开了10个线程 ,这20人都要上厕所
            t = Thread(target=task)
            t.start()
    
    Semaphore举例
    #####################################
     Thread-1上厕所
     Thread-2上厕所
     Thread-3上厕所
     Thread-4上厕所
     Thread-5上厕所
     Thread-2上完厕所走了
     Thread-6上厕所
     Thread-4上完厕所走了 
     Thread-1上完厕所走了
     Thread-7上厕所
    
     Thread-3上完厕所走了 
     Thread-8上厕所
     Thread-5上完厕所走了
    
     Thread-9上厕所
     Thread-10上厕所
     Thread-8上完厕所走了 
     Thread-10上完厕所走了
    
     Thread-6上完厕所走了
     Thread-7上完厕所走了
     Thread-9上完厕所走了

原文地址:https://www.cnblogs.com/daviddd/p/12034419.html