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('主')
posted @ 2019-10-24 20:57  🍞面包🍞  阅读(107)  评论(0编辑  收藏  举报