• day 31


    day 31 Event、进or线程池、协程、IO模型

    01.Event

    1. 调用该类实例化一个对象 e = Event()

    2. 若该方法出现在任务中会进入阻塞态

    3. 用一些线程控制其他线程的状态

    4. from threading import Event
      from threading import Thread
      import time
      
      e = Event() # 创建一个Event对象,初始值为Fales,可通过e.is_set()查看
      
      def func1():
          print('func1运行')
          time.sleep(5)
          e.set() # 将对象e的值设置为True
          print('func1结束')
      
      def func2(name):
          print(f'{name}正在等待')
          e.wait() # 当对象e的值为True时往下执行
          print(f'{name}等待结束')
      
      t=Thread(target=func1)
      t.start()
      
      for i in range(10):
          t=Thread(target=func2,args=(i,))
          t.start()
      

    02.线程池与进程池

    1. 进程池与线程池是用来控制当前程序允许进程/线程的数量

    2. 保证在硬件允许的范围内创建(进程/线程)的数量

    3. from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
      ProcessPoolExecutor(5) # 表示只能同时开启5个进程,默认以CPU核心个数
      ThreadPoolExecutor(5) # 表示只能同时开启5个线程,默认以CPU数*5
      
    4. from concurrent.futures import ThreadPoolExecutor
      import time
      
      pool = ThreadPoolExecutor(3) # 实例化对象以调用
      
      def func1(res):
          print(f'{res}开始')
          time.sleep(1)
          print('结束')
          return 123
      
      def func2(res):
          print(type(res)) # 传入的res为一个对象
          res2=res.result() # 通过result()的方法将上一线程的值取出
          print(res2)
      
      for i in range(5):
          pool.submit(func1,1).add_done_callback(func2)
      	#	调用对象自动创建线程,将函数对象和参数传入。设置接收函数
      pool.shutdown() # 如同join()保证子线程结束后在往下运行主线程
      print('主')
      
    5. pass

    03.协程

    1. 单线程下通过手动模拟操作系统的多道技术实现并发(切换+保存状态)

    2. 优点;在IO密集型下,会提高效率

    3. 缺点;在计算密集型下,会降低效率

    4. # 使用gevent实现单线程下遇到IO操作自动切换状态
      from gevent import monkey
      import time
      from gevent import spawn,joinall
      
      monkey.patch_all() # 监听该程序下的所有IO操作
      
      def func1():
      		print(1)
          time.sleep(1)
          print('1over')
      def func2():
        	print(2)
          time.sleep(3)
          print('2over')
      def func3():
        	print(3)
          time.sleep(2)
          print('3over')
      start_time=time.time()
      s1 = spawn(func1) # 模拟并发,spawn内的函数在遇到IO时就会(保存状态+切换)向下运行
      s2 = spawn(func2)
      s3 = spawn(func3)
      joinall([s1,s2,s3]) # 相当于s1.join(),s2.join(),s3.join()
      end_time=time.time()
      print(end_time-start_time)
      
    5. pass

    04.IO模型

    1. blocking IO;阻塞IO
    2. nonblocking IO;非阻塞IO
    3. multiplexing IO;多路复用IO
    4. Asynchronous IO;异步IO

    05.单线程下模拟并发TCP服务端

    # server
    import socket
    import json
    import struct
    from gevent import monkey,spawn
    monkey.patch_all()
    
    server = socket.socket()
    server.bind(('127.0.0.1',9608))
    server.listen(5)
    print('启动服务器')
    
    def working(conn):
        unm=1
        while True:
            try:
              headers=conn.recv(4)
              if not headers:
                  continue
              data_len=struct.unpack('i',headers)[0]
              bytes_data=conn.recv(data_len)
              back_dic=json.loads(bytes_data.decode('utf-8'))
              print(unm)
              unm+=1
              msg={'msg':back_dic['msg'].upper()}
              bytes_msg=json.dumps(msg)
              msg_len=struct.pack('i',len(bytes_msg))
              conn.send(msg_len)
              conn.send(bytes_msg.encode('utf-8'))
            except Exception as e:
                print(e)
                break
    def server2():
        while True:
            conn,addr = server.accept()
            spawn(working,conn)
    if __name__ == '__main__':
        s1=spawn(server2)
        s1.join()
    
    # client
    import socket
    import json
    import struct
    from concurrent.futures import ThreadPoolExecutor
    pool=ThreadPoolExecutor(60)
    
    def client(i):
        c1=socket.socket()
        c1.connect(('127.0.0.1',9608))
        print('启动客户端')
        num=1
        while True:
            try:
                send_dic={'msg':f'{i}hello{num}'}
                bytes_send=json.dumps(send_dic)
                num+=1
                send_len=struct.pack('i',len(bytes_send))
                c1.send(send_len)
                c1.send(bytes_send.encode('utf-8'))
                data_len=c1.recv(4)
                if not data_len:
                    continue
                dic_len=struct.unpack('i',data_len)[0]
                data_dic=c1.recv(dic_len)
                msg_dic=json.loads(data_dic.decode('utf-8'))
                print(msg_dic['msg'])
            except Exception as e:
                print(e)
                break
        c1.close()
    
    for i in range(60):
        pool.submit(client,i)
    pool.shutdown()
    print('主')
    
  • 相关阅读:
    面向对象 委托
    面向对象 继承 接口
    C# 面向对象 , 类与对象
    C# 知识点回顾
    SQL 数据库知识点回顾
    C# 10 总复习
    spring boot jpa 表关联查询分组 group by 去重
    钉钉新增考勤组 设置考勤规则
    elasticsearch 学习之父子关联查询 parent/child
    Elasticsearch 查询学习
  • 原文地址:https://www.cnblogs.com/luocongyu/p/11734868.html
Copyright © 2020-2023  润新知