异步io和协程

常见的异步io模块asyncio、gevent、twisted、tornado

核心技术为select()和协程

异步io请求的本质则是【非阻塞Socket】+【IO多路复用】

协程在这里不是一个必须使用的技术,在使用select()事件驱动循环本身就可以达到单线程异步的效果

io协程在遇到阻塞时进行切换,其实现需要依赖select()事件循环进行切换

协程本质是一种上下文切换技术,通过生成器yield记录状态的特性来实现

r,w,e = select.select([rlist],[wlist],[error],timeout)
select:采用事件轮询方式,即在while True下不断轮询所有的socket,
某个socket有数据返回时通知用户进程,最大轮询事件为1024,可以跨平台,水平触发
poll:方式相同,没有最大轮询事件数量限制
epoll:方式不同,比如100个连接,有两个活跃了,epoll会告诉用户这两个两个活跃了,直接取就ok了,而select是循环一遍。

select/epoll的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。

如果处理的连接数不是很高的话,使用select/epoll的web server不一定比使用multi-threading + blocking IO
的web server性能更好,可能延迟还更大。

 1 import socket,select
 2 
 3 socket_list = [
 4     ('www.baidu.com',80),
 5     ('202.89.233.100',80),
 6     ('101.37.225.65',80),
 7 ]
 8 soc_list = []
 9 conn_list=[]
10 for s in socket_list:
11     c = socket.socket()
12     c.setblocking(False)
13     try:
14         c.connect(s)
15     except Exception as e:
16         pass
17     soc_list.append(c)
18     conn_list.append(c)
19 print(soc_list)
20 while True:
21     r,w,error = select.select(soc_list,conn_list,[])
22     for i in soc_list:
23         try:
24             while True:
25                 data = i.sock.recv(8096)
26                 print(i)
27                 if not data:
28                     soc_list.remove(i)
29         except Exception as e:
30             pass
31 
32     for i in conn_list:
33         i.sendall("""GET /index HTTP/1.0
Host: www.baidu.com

""")
34         conn_list.remove(i)
异步io客户端

 生产者消费者的例子,yield from的简单用法

yield from用来向生成器(协程)传送数据 ,等价于for i in generator(): yield i

v= yield from  ,v为generator()的返回值

 1 def consumer_work():
 2     i=''
 3     while True:
 4         n = yield
 5         if n is None:
 6             break
 7         print('吃了包子%s' % n)
 8     return 'end'
 9 
10 def consumer(con):
11     while True:
12         v = yield from con
13         print(v)
14 
15 def producer(c):
16     next(c)
17     for i in range(10):
18         print('生产了包子%s' % i)
19         c.send(i)
20     c.send(None)
21 
22 
23 con = consumer_work()
24 c = consumer(con)
25 producer(c)
生产者消费者
原文地址:https://www.cnblogs.com/cx59244405/p/8464945.html