zoukankan      html  css  js  c++  java
  • python中的selectors模块

    它的功能与linux的epoll,还是select模块,poll等类似;实现高效的I/O multiplexing, 常用于非阻塞的socket的编程中;
    python文档:https://docs.python.org/3/library/selectors.html

    1. 模块定义了一个 BaseSelector的抽象基类, 以及它的子类,包括:SelectSelector, PollSelector, EpollSelector, DevpollSelector, KqueueSelector.    
    另外还有一个DefaultSelector类,它其实是以上其中一个子类的别名而已,它自动选择为当前环境中最有效的Selector,所以平时用 DefaultSelector类就可以了,其它用不着。
    
    2. 模块定义了两个常量,用于描述 event Mask
    EVENT_READ :      表示可读的; 它的值其实是1;
    EVENT_WRITE:      表示可写的; 它的值其实是2;
    
    3. 模块定义了一个 SelectorKey类, 一般用这个类的实例 来描述一个已经注册的文件对象的状态, 这个类的几个属性常用到:
    fileobj:   表示已经注册的文件对象;
    fd:          表示文件对象的描述符,是一个整数,它是文件对象的 fileno()方法的返回值;
    events:    表示注册一个文件对象时,我们等待的events, 即上面的event Mask, 是可读呢还是可写呢!!
    data:       表示注册一个文件对象是邦定的data;
    
    4. 最后说说抽象基类中的方法;
    register(fileobj, events, data=None)  
    作用:注册一个文件对象。
    参数: 
    fileobj——即可以是fd 也可以是一个拥有fileno()方法的对象; 
    events——上面的event Mask 常量; 
    data返回值: 一个SelectorKey类的实例;
    
    unregister(fileobj)
    作用: 注销一个已经注册过的文件对象;      
    返回值:一个SelectorKey类的实例;
    
    modify(fileobj, events, data=None)    
    作用:用于修改一个注册过的文件对象,比如从监听可读变为监听可写;它其实就是register() 后再跟unregister(),但是使用modify( ) 更高效;
    返回值:一个SelectorKey类的实例;
    
    select(timeout=None)
    作用: 用于选择满足我们监听的event的文件对象;
    返回值: 是一个(key, events)的元组, 其中key是一个SelectorKey类的实例, 而events 就是 event Mask(EVENT_READ或EVENT_WRITE,或者二者的组合)
    
    close()
    作用:关闭 selector。 最后一定要记得调用它, 要确保所有的资源被释放;
    
    get_key(fileobj)
    作用: 返回注册文件对象的 key;
    返回值 :一个SelectorKey类的实例;
    

    根据socket通信实例熟悉一下selectors模块

    socket server端代码:

    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    """
    IO多路复用之selectors模块
    selectors模块帮我们选择当前操作系统平台下最合适的IO多路复用机制
        有epoll就用epoll
        有poll就用poll
        有select就用select
    """
    import selectors
    import socket
    
    
    def to_accept(sock, mask):
        conn, addr = sock.accept()
        conn.setblocking(False)
        sel.register(fileobj=conn, events=selectors.EVENT_WRITE, data=to_read)
    
    
    def to_read(conn, mask):
        try:
            recvs = conn.recv(1024)
            if not recvs:
                sel.unregister(fileobj=conn)
                conn.close()
                return
            print(recvs.decode(encoding='utf-8'))
            sel.unregister(fileobj=conn)
            wdict[conn] = b'%s' % (recvs, )
            sel.register(fileobj=conn, events=selectors.EVENT_WRITE, data=to_write)
        except ConnectionResetError:
            sel.unregister(fileobj=conn)
            conn.close()
            return
    
    
    def to_write(conn, mask):
        # print(mask)  # EVENT_READ 值为1, EVENT_WRITE 值为2
        conn.sendall(wdict.get(conn))
        wdict.pop(conn)
        sel.unregister(fileobj=conn)
        sel.register(fileobj=conn, events=selectors.EVENT_READ, data=to_read)
    
    
    sk = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
    
    sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    
    sk.bind(('', 8080))
    
    sk.listen(32)
    
    sk.setblocking(False)  
    sel = selectors.DefaultSelector()
    
    sel.register(fileobj=sk, events=selectors.EVENT_READ, data=to_accept)
    
    wdict = dict()
    
    while 1:
        events = sel.select(timeout=None)
        for sel_obj, mask in events:
            callback = sel_obj.data
            callback(sel_obj.fileobj, mask)
    

    socket client 端

    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    
    import socket
    import threading
    
    
    def my_client():
        sk = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
        sk.connect(('localhost', 8080))
        while 1:
            sk.send(b'hi')
            msg = sk.recv(1024)
            print(msg)
    
    
    for i in range(10):
        threading.Thread(target=my_client).start()
    
  • 相关阅读:
    Matlab高级教程_第二篇:Matlab相见恨晚的模块_02_并行运算-1
    Matlab高级教程_第一篇:Matlab基础知识提炼_06
    利用ubuntu的alias命令来简化许多复杂难打的命令
    无线路由设置
    解决Ubuntu下使用命令行subl 打开Sublime text3无法输入中文的问题
    ubuntu 14.04 lamp 安装与配置
    ubuntu14.04 login loop issue
    机器学习资源大全
    技巧:利用putty通过win7访问ubuntu
    使用XML-RPC进行远程文件共享
  • 原文地址:https://www.cnblogs.com/nyist-xsk/p/13385684.html
Copyright © 2011-2022 走看看