• 异步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)
    生产者消费者
  • 相关阅读:
    java 中 this 和 super 说明及在构造器中super()和this()相互调用执行顺序
    Java中get()方法和set()方法如何使用?
    java中如何在键盘中输入一串数字然后存入数组中?
    修改阿里云服务器主机名称
    flask第一个页面
    爬取汽车之家新闻的数据
    冒泡排序
    爬取简书
    Mac Flask-Migrate 安装出现错误
    C++__ 判断和循环
  • 原文地址:https://www.cnblogs.com/cx59244405/p/8464945.html
Copyright © 2020-2023  润新知