第三篇:协程
协程的介绍
""" 进程:资源单位 线程:执行单位 协程:单线程下实现并发(这个概念完全是由程序员意淫出来的,根本不存在) 程序员在代码层面上检测所有的IO操作,一旦遇到IO,将在代码级别完成切换 这样给CPU的感觉是这个程序一直运行,没有IO,从而提升程序的运行效率 多道技术 切换+保存状态 CPU两种切换(1.程序遇到IO 2.程序长时间占用) 代码如何做到切换+保存状态 切换 切换不一定提高效率,也可能降低效率 IO切 提升 没有IO切 降低 保存状态 保存上一次执行的状态,下一次来接着执行上一次的操作继续往后执行 yield """
验证切换是否一定能提高效率
# 串行执行计算密集型任务 0.5209994316101074 import time def func1(): for i in range(10000000): i + 1 def func2(): for i in range(10000000): i + 1 start_time = time.time() func1() func2() print(time.time() - start_time) # 切换 + yield 0.7936575412750244 import time def func1(): while True: 10000000 + 1 yield def func2(): g = func1() # 先初始化出生成器 for i in range(10000000): i + 1 next(g) start_time = time.time() func2() print(time.time() - start_time)
gevent模块(了解)
安装:pip3 install gevent
from gevent import monkey;monkey.patch_all() import time from gevent import spawn ''' gevent模块本身无法检测常见的一些io操作 在使用的时候需要你额外的导入一句话 from gevent import monkey monkey.patch_all() 由于上面的两句话在使用gevent模块的时候是肯定要导入的,支持简写 from gevent import monkey;monkey.patch_all() ''' def heng(): print('哼') time.sleep(2) print('哼') def ha(): print('哈') time.sleep(3) print('哈') def heiheihei(): print('heiheihei') time.sleep(3) print('heiheihei') start_time = time.time() g1 = spawn(heng) g2 = spawn(ha) g3 = spawn(heiheihei) g1.join() g2.join() g3.join() print(time.time() - start_time) # 3.109663963317871
协程实现TCP服务端的并发
# 服务端 from gevent import monkey;monkey.patch_all() import socket from gevent import spawn def communication(conn): while True: try: data = conn.recv(1024) if len(data) == 0: break conn.send(data.upper()) except ConnectionResetError as e: print(e) break conn.close() def server(ip, port): server = socket.socket() server.bind((ip, port)) server.listen(5) while True: conn, addr = server.accept() spawn(communication, conn) if __name__ == '__main__': g1 = spawn(server, '127.0.0.1', 8080) g1.join() # 客户端 from threading import Thread, current_thread import socket def x_client(): client = socket.socket() client.connect(('127.0.0.1',8080)) n = 0 while True: msg = '%s say hello %s'%(current_thread().name,n) n += 1 client.send(msg.encode('utf-8')) data = client.recv(1024) print(data.decode('utf-8')) if __name__ == '__main__': for i in range(500): t = Thread(target=x_client) t.start()
理想状态:
我们可以通过多进程下面开设多线程,多线程下面开设协程程序,从而使我们的程序执行效率提高