协程和IO模型
协程
1.什么是协程
单线程实现并发
在应用程序里控制多个任务的切换+保存状态
优点:
应用程序级别速度要远远高于操作系统的切换
缺点:
多个任务一旦有一个阻塞没有切,整个线程都阻塞在原地
该线程内的其他的任务都不能执行了
一旦引入协程,就需要检测单线程下所有的IO行为,实现遇到IO就切换,少一个 都不行,因为一旦一个任务阻塞了,整个线程就阻塞了,其他的任务即便是可以计算, 但是也无法运行了
2.协程的目的:
想要在单线程下实现并发
并发指的是多个任务看起来是同时运行的
并发 = 切换+保存状态
3.协程的应用
from gevent import monkey,spawn;monkey.patch_all() from threading import current_thread import time def eat(): print('%s eat 1' %current_thread().name) time.sleep(3) print('%s eat 2' %current_thread().name) def play(): print('%s play 1' %current_thread().name) time.sleep(1) print('%s play 2' %current_thread().name) g1=spawn(eat,) g2=spawn(play,) print(current_thread().name) g1.join() g2.join()
IO模型
recvfrom:
wait data:等待客户端产生数据-->客户端OS-->网络-->服务端操作系统
copy data:由本地操作系统缓存中的数据拷贝到应用程序的内存中
send:
copy data
非阻塞io模型
import socket server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind(('127.0.0.1',8080)) server.listen(5) server.setblocking(False) conn_list = [] while True: try: print('当前连接数%s'%len(conn_list)) conn,client_addr = server.accept() conn_list.append(conn) print('连接成功') except BlockingIOError: del_conn = [] for i in conn_list: try: msg = i.recv(1024) if len(msg) == 0: del_conn.append(i) continue i.send(msg.upper()) except BlockingIOError: pass except ConnectionResetError: del_conn.append(i) for i in del_conn: conn_list.remove(i)