zoukankan      html  css  js  c++  java
  • python库之selectors

      在之前的博客中已经总结过分别在windows和linux操作系统下实现socket高并发(I/O异步)的方法,可以参考基于epoll的TP传输层实现Windows之IOCP

      下面对Python中实现socket高并发的selectors库进行总结,官方参考文档:https://docs.python.org/3/library/selectors.html 

    1. 示例代码

    import selectors
    import socket
    
    sel = selectors.DefaultSelector()
    
    def accept(sock, mask):
        conn, addr = sock.accept()  # Should be ready
        print('accepted', conn, 'from', addr)
        conn.setblocking(False)
        sel.register(conn, selectors.EVENT_READ, read)
    
    def read(conn, mask):
        data = conn.recv(1000)  # Should be ready
        if data:
            print('echoing', repr(data), 'to', conn)
            conn.send(data)  # Hope it won't block
        else:
            print('closing', conn)
            sel.unregister(conn)
            conn.close()
    
    sock = socket.socket()
    sock.bind(('localhost', 1234))
    sock.listen(100)
    sock.setblocking(False)
    sel.register(sock, selectors.EVENT_READ, accept)
    
    while True:
        events = sel.select()
        for key, mask in events:
            callback = key.data
            callback(key.fileobj, mask)

       上面示例代码来自官方文档,接下来对关键代码进行重点说明

    2. 重点知识说明

    (1)conn.setblocking(False)

      设置socket的阻塞或非阻塞模式

      阻塞模式下当试图对该文件描述符进行读写时,如果当时没有东西可读,或者暂时不可写,程序就进入等待状态,直到有东西可读或者可写为止

      非阻塞模式下如果没有东西可读,或者不可写,读写函数马上返回,而不会等待

    (2)sel.register(conn, selectors.EVENT_READ, read)

      对描述符进行注册,也就是对该描述符的EVENT_READ事件进行监听,当又READ事件通知时,调用回调函数read

      selectors库提供了两个监听事件:EVENT_READ和EVENT_WRITE

    (3)sel.unregister(conn)

      注销描述符

    (4)events = sel.select()

      函数原型为:abstractmethod select(timeout=None)

      该函数是实现I/O异步的关键,等待,直到一些已注册的文件对象准备就绪,或者超时。

      如果timeout>0,则指定最大等待时间,以秒为单位,如果超时没有,则调用将阻塞,直到被监视的文件对象准备就绪。如果timeout< 0,调用将不会阻塞,并将报告当前就绪的文件对象。

      该函数返回一个元组(key, events)

      key为class selectors.SelectorKey对象,SelectorKey = namedtuple('SelectorKey', ['fileobj', 'fd', 'events', 'data'])

      fileobj为注册的文件对象

      fd为文件描述符

      data为与文件对象相关联的自定义数据,如上面的回调函数

      明确上面的4个知识点后会觉得selectors库的使用很简单

      最后对DefaultSelector进行说明,DefaultSelector会根据当前操作系统类型自己选择selector类型

    if 'KqueueSelector' in globals():
        DefaultSelector = KqueueSelector
    elif 'EpollSelector' in globals():
        DefaultSelector = EpollSelector
    elif 'DevpollSelector' in globals():
        DefaultSelector = DevpollSelector
    elif 'PollSelector' in globals():
        DefaultSelector = PollSelector
    else:
        DefaultSelector = SelectSelector
  • 相关阅读:
    linux每日命令(31):tar命令
    Django——model基础
    Django——模板层(template)(模板语法、自定义模板过滤器及标签、模板继承)
    Django
    linux每日命令(30):Linux 用户及用户组相关文件、命令详解
    linux每日命令(29):chown命令
    20170430深圳Meetup
    静态库嵌套引用问题
    JD-Store购物网站复盘——20170312
    20170305Meetup Git、heroku drop db
  • 原文地址:https://www.cnblogs.com/xiaobingqianrui/p/9882599.html
Copyright © 2011-2022 走看看