GIL全局解释器锁死锁递归锁信号量

      GIL全局解释器锁

      GIL全局解释器锁:基于cpython来研究解释器锁

      1. GIL本质上是一个互斥锁

      2. GIL的目的是为了阻止同一个进程内多个线程同时执行(并发)

        单个进程下的多个线程无法实现并行,但是能实现并发

      3. 这把锁主要是因为cpython的内存管理不是“线程安全”的

        1. 内存管理:

          垃圾回收机制

      GIL的存在就是为了保证线程的安全

      注意:

      多个线程过来执行,一旦遇到io操作,就会立马释放GIL解释锁,交给下一个先进来的线程

      多线程的作用:

      站在两个角度看问题

      '''
      四个任务计算密集型,每个任务需要10s:
         单核:
              开启进程:
                  消耗资源过大
                  4个进程:40s
              开启线程:
                  消耗资源远小于进程
                  4个线程:40s
          
         多核:
              开启进程
                  并行执行,效率比较高
                  4个进程: 10s
      
              开启线程
                  并发执行,执行效率低.
                  4个线程: 40s
                  
                  
                  
                  
      四个任务, IO密集型, 每个任务需要10s:
         单核:
              开启进程
                 消耗资源过大
                  4个进程: 40s
      
              开启线程
                 消耗资源远小于进程
                 4个线程: 40s
      
          多核:
              开启进程
                 并行执行,效率小于多线程,因为遇到IO会立马切换CPU的执行权限
                 4个进程: 40s  +  开启进程消耗的额外时间
      
              开启线程
                 并发执行,执行效率高于多进程
                 4个线程: 40s
         
      
      ''' 
      from threading import Thread
      from multiprocessing import Process
      import os
      import time
      
      
      # 计算密集型
      def work1():
          number = 0
          for line in range(100000000):
              number += 1
      
      
      # IO密集型
      def work2():
          time.sleep(1)
      
      
      if __name__ == '__main__':
          # 测试计算密集型
          # print(os.cpu_count())  # 6
          # # 开始时间
          # start_time = time.time()
          # list1 = []
          # for line in range(6):
          #     p = Process(target=work1)  # 程序执行时间5.300818920135498
          #     # p = Thread(target=work1)  # 程序执行时间24.000795602798462
          #
          #     list1.append(p)
          #     p.start()
      
          # 测试IO密集型
          print(os.cpu_count())  # 6
          # 开始时间
          start_time = time.time()
          list1 = []
          for line in range(40):
              # p = Process(target=work2)  # 程序执行时间4.445072174072266
              p = Thread(target=work2)  # 程序执行时间1.009237289428711
      
              list1.append(p)
              p.start()
      
          for p in list1:
              p.join()
          end_time = time.time()
      
          print(f'程序执行时间{end_time - start_time}')
      
          
      # 在计算密集型的情况下:使用多进程    
      
      # 在IO密集型的情况下:使用多线程    
      
      # 高效执行多个进程,内多个IO密集型的程序:使用 多进程 + 多线程

      死锁现象和递归锁

      from threading import Lock, Thread, current_thread,Rlock
      import time
      
      mutex_a = Lock()
      mutex_b = Lock()
      #
      # print(id(mutex_a))
      # print(id(mutex_b))
      
      
      '''
      递归锁:用于解决死锁问题
      
      RLock:比喻成一个万能钥匙,可以供给多个人去使用,但是
             第一个使用的时候,会对该锁做一个引用计数,只有
             引用计数为0时,才能真正释放让另一个人去使用
      '''
      
      
      
      mutex_a = mutex_b = RLock() 
      
      class MyThread(Thread):
      
          # 线程执行任务
          def run(self):
              self.func1()
              self.func2()
      
          def func1(self):
              mutex_a.acquire()
              # print(f'用户{current_thread().name}抢到锁a')
              print(f'用户{self.name}抢到锁a')
              mutex_b.acquire()
              print(f'用户{self.name}抢到锁b')
              mutex_b.release()
              print(f'用户{self.name}释放锁b')
              mutex_a.release()
              print(f'用户{self.name}释放锁a')
      
          def func2(self):
              mutex_b.acquire()
              print(f'用户{self.name}抢到锁b')
              # IO操作
              time.sleep(1)
      
              mutex_a.acquire()
              print(f'用户{self.name}抢到锁a')
              mutex_a.release()
              print(f'用户{self.name}释放锁a')
              mutex_b.release()
              print(f'用户{self.name}释放锁b')
      
      
      for line in range(10):
          t = MyThread()
          t.start()

      注意

      锁不能乱用

      信号量

      互斥锁:比喻成一个家用马桶。同时只能让一个人去使用

      信号量:比喻成公厕多个马桶。同一时间可以让多个人去使用

      from threading import Seaphore,Lock,Thread,current_thread 
      import time
      
      sm=Semaphore(5)
      muetx=Lock
      
      def task():
          
          sm.acquier()
          print(f'{current_thread().name}执行任务')
          time.sleep(1)
          sm.release()
          
          
      for line in range(20):
          t=Thread(target=task)
          t.start()

      线程队列

      FIFO队列:

      先进先出

      LIFO队列:

      后进先出

      优先级队列

      根据参数内的,数字的大小进行分级,数字越小,优先级越高

      # 普通的线程队列: 先进先出
      # q = queue.Queue()
      # q.put(1)
      # q.put(2)
      # q.put(3)
      # print(q.get())  # 1
      
      
      # LIFO队列: 后进先出
      # q = queue.LifoQueue()
      # q.put(1)
      # q.put(2)
      # q.put(3)
      # print(q.get())  # 3
      
      
      # 优先级队列
      q = queue.PriorityQueue()  # 超级了解
      # 若参数中传的是元组,会以元组中第一个数字参数为准
      q.put(('a优', '先', '娃娃头', 4))  # a==97
      q.put(('a先', '优', '娃娃头', 3))  # a==98
      q.put(('a级', '级', '娃娃头', 2))  # a==99
      '''
      1.首先根据第一个参数判断ascii表的数值大小
      2.判断第个参数中的汉字顺序.
      3.再判断第二参数中数字--> 字符串数字 ---> 中文
      4.以此类推
      '''
      print(q.get())
      相关文章
      相关标签/搜索
      今期管家婆大图 玄机图香港挂牌正版彩图六合彩资料大全香港马会资料白小姐中特玄机香港挂牌之全篇