day30总结

      回顾

      1.进程互斥锁
      让并发变成串行,牺牲了效率,保证数据安全.
      mutex = Lock()
      # 加锁
      ? mutex.acquire()
      # 释放锁
      ? mutex.release()

      2.队列:
      相当于在内存中开启了一个空间,可以存放一堆数据,这堆数据都得遵循"先进先出".
      管道(阻塞) + 锁
      q = Queue()
      # 添加数据
      ? q.put(1)
      # 若队列满了,会原地等待
      ? q.put(2)
      # 若队列满了,不会等待直接报错
      ? q.put_nowait(2)

      获取数据,遵循先进先出
      若队列中没数据,会原地等待
      q.get() # 1
      若队列中没数据,会直接报错
      q.get_nowait() # 1

      q.empty() # 判断队列是否为空
      q.full() # 判断队列是否满了

      3.IPC进程间通信
      通过队列让进程间实现通信.

      4.生产者与消费者
      生产者: 生产数据的
      消费者; 使用数据的

      目的: 解决供需不平衡问题.
      通过队列来实现,生产者消费者供需不平衡问题.

      5.线程
      1.什么是线程?
      进程: 资源单位
      线程: 执行单位

      注意: 只要开启一个进程就会有一个线程(主线程).
      主线程会在进程结束时,一并销毁.

      2.为什么要使用线程?
      节省内存资源

      开启进程:
      1) 开辟一个新的内存空间
      2) 会自带一个主线程

      开启线程:
      1) 一个进程内可以开启多个线程
      2) 开启线程的资源远小于进程

      创建线程的两种方式
      一:
      from threading import Thread
      def task():
      pass

      t = Thread(target=task) # 异步提交任务,开启线程
      t.start()
      t.join() # 主线程等待子线程结束之后再结束.

      二:
      class MyThread(Thread):
      def run(self):
      执行任务
      ? pass

      t = MyThread()
      t.start()
      t.join()

      6.线程对象的属性
      current_thread().name # 获取当前线程对象的名字
      # 返回一个列表,列表中包含当前执行的所有线程对象
      print(enumerate())
      # 获取当前执行线程的个数
      print(activeCount())
      is_alive() # 判断线程是否存活

      7.线程互斥锁
      from threading import Lock()
      mutex = Lock()
      mutex.acquire()
      t1
      mutex.release()

      TCP服务端实现并发

      '''
      服务端的工作:
          1.接收客户端的请求
          2.24小时不间断提供服务
          3.实现并发
      
      '''
      
      import socket
      import time
      from threading import Thread
      
      server = socket.socket()
      
      server.bind(
          ('127.0.0.1', 9527)
      )
      
      server.listen(5)
      print('启动服务端...')
      
      
      # 线程任务,执行接收客户端消息与发送消息给客户端
      def working(conn):
          while True:
              try:
                  data = conn.recv(1024)
                  if len(data) == 0:
                      break
                  print(data)
                  time.sleep(1)
                  conn.send(data.upper())
              except Exception as e:
                  print(e)
                  break
      
          conn.close()
      
      
      while True:
          conn, addr = server.accept()
          print(addr)
          t = Thread(target=working, args=(conn, ))
          t.start()xxxxxxxxxx?'''服务端的工作: ?  1.接收客户端的请求 ?  2.24小时不间断提供服务 ?  3.实现并发'''import socketimport timefrom threading import Threadserver = socket.socket()server.bind( ?  ('127.0.0.1', 9527))server.listen(5)print('启动服务端...')# 线程任务,执行接收客户端消息与发送消息给客户端def working(conn): ?  while True: ? ? ?  try: ? ? ? ? ?  data = conn.recv(1024) ? ? ? ? ?  if len(data) == 0: ? ? ? ? ? ? ?  break ? ? ? ? ?  print(data) ? ? ? ? ?  time.sleep(1) ? ? ? ? ?  conn.send(data.upper()) ? ? ?  except Exception as e: ? ? ? ? ?  print(e) ? ? ? ? ?  break ?  conn.close()while True: ?  conn, addr = server.accept() ?  print(addr) ?  t = Thread(target=working, args=(conn, )) ?  t.start()'''服务端的工作: ?  1.接收客户端的请求 ?  2.24小时不间断提供服务 ?  3.实现并发'''import socketimport timefrom threading import Threadserver = socket.socket()server.bind( ?  ('127.0.0.1', 9527))server.listen(5)print('启动服务端...')# 线程任务,执行接收客户端消息与发送消息给客户端def working(conn): ?  while True: ? ? ?  try: ? ? ? ? ?  data = conn.recv(1024) ? ? ? ? ?  if len(data) == 0: ? ? ? ? ? ? ?  break ? ? ? ? ?  print(data) ? ? ? ? ?  time.sleep(1) ? ? ? ? ?  conn.send(data.upper()) ? ? ?  except Exception as e: ? ? ? ? ?  print(e) ? ? ? ? ?  break ?  conn.close()while True: ?  conn, addr = server.accept() ?  print(addr) ?  t = Thread(target=working, args=(conn, )) ?  t.start()
      import socket
      import time
      
      client = socket.socket()
      
      client.connect(
          ('127.0.0.1', 9527)
      )
      
      print('启动客户端...')
      while True:
          client.send(b'hello')
          data = client.recv(1024)
          print(data)
          time.sleep(1)

      GIL全局解释器锁

      '''
      In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple
      native threads from executing Python bytecodes at once. This lock is necessary mainly
      because CPython’s memory management is not thread-safe. (However, since the GIL
      exists, other features have grown to depend on the guarantees that it enforces.)
      
      在CPython中,全局解释器锁(GIL)是一个防止多个锁的互斥锁
      本机线程从执行Python字节码一次。这把锁主要是必须的
      因为CPython的内存管理不是线程安全的。(然而,自从GIL
      存在时,其他功能已逐渐依赖于它所实施的保证。)
      
      '''
      
      '''
      python解释器:
          1.Cpython
              C
              
          2.Jpython
              java
              
          3.Ppython
              Python
      
      
      GIL全局解释器锁:
          基于Cpython来研究全局解释器锁.
          
          1.GIL本质上是一个互斥锁.
          2.GIL的为了阻止同一个进程内多个线程同时执行(并行)
              - 单个进程下的多个线程无法实现并行,但能实现并发
          
          3.这把锁主要是因为CPython的内存管理不是 "线程安全" 的.
              - 内存管理
                  - 垃圾回收机制
                  
          GIL的存在就是为了保证线程安全的.
          
          注意: 多个线程过来执行,一旦遇到IO操作,就会立马释放GIL解释器锁,交给下一个先进来的线程.
          
      '''
      
      import time
      from threading import Thread, current_thread
      
      number = 100
      
      
      def task():
          global number
          number2 = number
          # time.sleep(1)
          number = number2 - 1
          print(number, current_thread().name)
      
      
      for line in range(100):
          t = Thread(target=task)
          t.start()

      验证多线程的作用

      '''
      多线程的作用:
          站在两个角度去看问题:
      
          - 四个任务, 计算密集型, 每个任务需要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
      import time
      
      mutex_a = Lock()
      mutex_b = Lock()
      #
      # print(id(mutex_a))
      # print(id(mutex_b))
      
      
      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()
      
      
      '''
      注意:
          锁不能乱用.
      '''

      递归锁

      '''
      递归锁(了解):
          用于解决死锁问题.
      
      RLock: 比喻成万能钥匙,可以提供给多个人去使用.
          但是第一个使用的时候,会对该锁做一个引用计数.
          只有引用计数为0, 才能真正释放让另一个人去使用
      '''
      
      from threading import RLock, Thread, Lock
      import time
      
      mutex_a = mutex_b = Lock()
      
      
      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 Semaphore, Lock
      from threading import current_thread
      from threading import Thread
      import time
      
      sm = Semaphore(5)  # 5个马桶
      mutex = Lock()  # 5个马桶
      
      
      def task():
          # mutex.acquire()
          sm.acquire()
          print(f'{current_thread().name}执行任务')
          time.sleep(1)
          sm.release()
          # mutex.release()
      
      
      for line in range(20):
          t = Thread(target=task)
          t.start()

      线程队列

      '''
      线程Q(了解级别1): 线程队列  面试会问: FIFO
      
          - FIFO队列: 先进先出
          - LIFO队列: 后进先出
          - 优先级队列: 根据参数内,数字的大小进行分级,数字值越小,优先级越高
      '''
      import queue
      
      # 普通的线程队列: 先进先出
      # 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())
      相关文章
      相关标签/搜索
      今期管家婆大图 玄机图香港挂牌正版彩图六合彩资料大全香港马会资料白小姐中特玄机香港挂牌之全篇 应城市| 隆尧县| 尤溪县| 乐亭县| 申扎县| 措勤县| 葫芦岛市| 镶黄旗| 上高县| 武穴市| 金昌市| 兴海县| 瑞丽市| 清新县| 定远县| 砀山县| 天气| 奉节县| 容城县| 驻马店市| 绵阳市| 东丽区| 云霄县| 唐河县| 星座| 谷城县| 房山区| 镇康县| 临沭县| 美姑县| 新宁县| 黎城县| 即墨市| 通海县| 东宁县| 龙南县| 锡林浩特市| 塘沽区| 桓仁| 乐东| 漳平市| 克拉玛依市| 莱西市| 崇明县| 彭州市| 恭城| 常山县| 谷城县| 通化县| 阿巴嘎旗| 通江县| 荔浦县| 旌德县| 眉山市| 东阳市| 新竹市| 庐江县| 祥云县| 长顺县| 海淀区| 肥东县| 安庆市| 万源市| 广南县| 新邵县| 厦门市| 烟台市| 衡水市| 文山县| 怀柔区| 兴仁县| 翁牛特旗| 西盟| 西乌珠穆沁旗| 通化市| 宁城县| 房山区| 祁连县| 宁明县| 民乐县| 南乐县| 河源市| 阜城县| 恩施市| 沂南县| 合阳县| 加查县| 紫金县| 会同县| 武夷山市| 永安市| 乳源| 湘西| 达孜县| 茌平县| 伊宁县| 榆中县| 怀宁县| 溧水县| 五指山市| 大埔县| 乐山市| 邓州市| 九台市| 锡林郭勒盟| 东丰县| 丰原市| 隆回县| 澜沧| 海南省| 顺义区| 吉安县| 阳朔县| 保靖县| 梧州市| 宜昌市| 将乐县| 义乌市| 和田县| 襄樊市| 稷山县| 桃江县| 抚松县| 潞西市| 平定县| 宁安市| 崇仁县| 灵川县| 南川市| 上杭县| 锦州市| 当雄县| 建昌县| 汕尾市| 浙江省| 普安县| 图片| 惠东县| 攀枝花市| 奉新县| 娄底市| 海口市| 苍溪县| 怀远县| 高安市| 久治县| 九龙县| 辽源市| 深州市| 德保县| 巴林右旗| 涟水县| 云阳县| 永登县| 逊克县| 延吉市| 平邑县| 临朐县| 庆云县| 南城县| 垦利县| 固原市| 颍上县| 安岳县| 南京市| 卢氏县| 南木林县| 安龙县| 贺兰县| 淄博市| 齐河县| 浏阳市| 横峰县| 卢龙县| 临澧县| 广水市| 神池县| 剑河县| 垣曲县| 青川县| 仁布县| 仁布县| 阿克苏市| 贵定县| 托克逊县| 岳阳县| 襄樊市| 建德市| 噶尔县| 平湖市| 洛隆县| 瑞金市| 牟定县| 五峰| 淮阳县| 黎平县| 大厂| 浦江县| 明光市| 平定县| 元谋县| 会东县| 沾化县| 天镇县| 沙坪坝区| 皮山县| 鄢陵县| 怀来县| 佛山市| 清涧县| 绥中县| 隆昌县| 阳信县| 五华县| 黄石市| 中牟县| 闻喜县| 资兴市| 乐清市| 双桥区| 彭水| 临泽县| 七台河市| 芮城县| 克山县| 利津县| 永川市| 剑川县| 荔波县| 荔波县| 章丘市| 汉沽区| 万盛区| 泗洪县| 潢川县| 陆川县| 佛坪县| 奎屯市| 木兰县| 安国市| 阿尔山市| 米脂县| 茶陵县| 博客| 神木县| 广饶县| 乌兰县| 昌乐县| 辽宁省| 正阳县| 日喀则市| 方山县| 新昌县| 庐江县| 宜兴市| 大连市| 加查县| 扶沟县| 资讯| 永济市| 通渭县| 卢氏县| 若尔盖县| 同心县| 商水县| 西昌市| 新和县| 长治市| 尉犁县| 兰坪| 泾阳县| 河北省| 乐山市| 巴东县| 竹北市| 泾源县| 盐城市| 南和县| 监利县| 皋兰县| 通化市| 柳河县| 屏东县| 兰州市| 平谷区| 津南区| 黄石市| 台州市| 岚皋县| 二连浩特市| 博湖县| 蒙城县| 施甸县| 太仓市| 三台县| 汉源县| 永福县| 胶州市| 郁南县| 罗田县| 怀柔区| 岑巩县| 兰溪市| 剑川县| 凌源市| 南澳县| 咸阳市| 辉南县| 平邑县| 南阳市| 余庆县| 六盘水市| 江北区| 乐至县| 宜阳县| 鹿泉市| 阿坝县| 望江县| 乌恰县| 金湖县| 五华县| 留坝县| 镇江市| 克山县| 武平县| 丰县| 奉节县| 进贤县| 颍上县| 锦州市| 咸阳市| 肇庆市| 寿光市| 宿迁市| 屯昌县| 古丈县| 油尖旺区| 棋牌| 盖州市| 余干县| 云霄县| 栖霞市| 钦州市| 广丰县| 德州市| 抚松县| 盐亭县| 安丘市| 界首市| 镇坪县| 义马市| 安新县| 华容县| 裕民县| 启东市| 九龙坡区| 怀集县| 凤冈县| 阳春市| 茶陵县| 安阳县| 孟津县| 洞头县| 克什克腾旗| 格尔木市| 泗阳县| 花莲县| 县级市| 乌审旗| 樟树市| 南部县| 那曲县| 湟源县| 阿鲁科尔沁旗| 金坛市| 和林格尔县| 新建县| 青阳县| 横山县| 电白县| 敖汉旗| 华坪县| 甘南县| 安岳县| 巍山| 庆阳市| 牙克石市| 藁城市| 公主岭市| 望奎县| 南城县| 临沭县| 乌兰浩特市| 北票市| 大同市| 富宁县| 舞钢市| 佛坪县| 资溪县| 宝兴县| 青冈县| 彝良县| 搜索| 延边| 黄平县| 白河县| 永登县| 宁河县| 石柱| 梅河口市| 吉林省| 新平| 上虞市| 石景山区| 舞钢市| 宜宾市| 卢龙县| 浦东新区| 华安县| 沙坪坝区| 大埔县| 监利县| 金乡县| 襄城县| 遂昌县| 新巴尔虎右旗| 安吉县| 新营市| 闽清县| 黄大仙区| 稷山县| 南雄市| 灵武市| 周口市| 尼木县| 融水| 安塞县| 台东县| 门头沟区| 海原县| 察雅县| 溆浦县| 牡丹江市| 当雄县| 新余市| 金平| 出国| 鄂托克前旗| 长宁县| 鹰潭市| 嘉祥县| 巩留县| 闵行区| 光泽县| 桃江县| 巴马| 儋州市| 平远县| 贵定县| 高雄市| 昌平区| 桃源县| 漳州市| 库尔勒市| 安义县| 六盘水市| 临洮县| 肇源县| 洞口县| 黑水县| 报价| 台湾省| 得荣县| 自治县| 华阴市| 祥云县| 巩留县| 深圳市| 江华| 临邑县| 晋城| 嵊泗县| 轮台县| 清水河县| 大埔县| 汉阴县| 集安市| 岳阳市| 屏山县| 宣汉县| 柳州市| 芜湖市| 正蓝旗| 拉萨市| 东山县| 尼勒克县| 壤塘县| 宜春市| 汽车| 象山县| 平武县| 泽州县| 乌海市| 菏泽市| 金沙县| 萨嘎县| 屏山县| 慈利县| 将乐县| 霍林郭勒市| 武宁县| 柏乡县| 广河县| 德庆县| 芜湖市| 通州市| 苗栗县| 金寨县| 辉县市| 开阳县| 山丹县| 景谷| 比如县| 富顺县| 蓬溪县| 德保县| 铅山县| 昌图县| 应用必备| 胶州市| 米林县| 永和县| 南丹县| 台北市| 九台市| 定南县| 宜昌市| 龙州县| 青铜峡市| 平乡县| 民勤县| 北京市| 张家川| 南和县| 青海省| 梁山县| 伊宁市| 明水县| 鲁甸县| 抚州市| 屏山县| 沙湾县| 绥中县| 舞阳县| 祁阳县| 舞阳县| 南平市| 富阳市| 宝坻区| 华宁县| 加查县| 建水县| 慈利县| 仙居县| 紫阳县| 义乌市| 九龙县| 定远县| 布拖县| 高碑店市| 泰顺县| 信宜市| 东兰县| 贡嘎县| 华亭县| 北海市| 平邑县| 辽中县| 青河县| 会理县| 彰武县| 荔波县| 定襄县| 大渡口区| 右玉县| 安义县| 申扎县| 通州区| 建湖县| 蒙城县| 玉山县| 东明县| 玉山县| 文登市| 乌兰浩特市| 三河市| 江口县| 潜山县| 金昌市| 金乡县| 福建省| 勐海县| 东台市| 新丰县| 房产| 内丘县| 建宁县| 安远县| 淄博市| 昌邑市| 平安县| 林周县| 德钦县| 怀集县| 建阳市| http://jx1870bidv.fun http://3g.jx1870bluev.fun http://www.jx1870crewv.fun http://www.jx1870creazv.fun http://jx1870betterv.fun http://m.jx1870chargev.fun http://wap.jx1870bushv.fun http://3g.jx1870bulletinv.fun http://3g.jx1870attezptv.fun http://wap.jx1870bowlv.fun http://3g.jx1870bandv.fun http://3g.jx1870describev.fun http://m.jx1870appropriatev.fun http://wap.jx1870causev.fun http://3g.jx1870cardv.fun http://www.jx1870debatev.fun http://wap.jx1870djv.fun http://wap.jx1870dropv.fun