登峰造极境

  • WIN
    • CSharp
    • JAVA
    • OAM
    • DirectX
    • Emgucv
  • UNIX
    • FFmpeg
    • QT
    • Python
    • Opencv
    • Openwrt
    • Twisted
    • Design Patterns
    • Mysql
    • Mycat
    • MariaDB
    • Make
    • OAM
    • Supervisor
    • Nginx
    • KVM
    • Docker
    • OpenStack
  • WEB
    • ASP
    • Node.js
    • PHP
    • Directadmin
    • Openssl
    • Regex
  • APP
    • Android
  • AI
    • Algorithm
    • Deep Learning
    • Machine Learning
  • IOT
    • Device
    • MSP430
  • DIY
    • Algorithm
    • Design Patterns
    • MATH
    • X98 AIR 3G
    • Tucao
    • fun
  • LIFE
    • 美食
    • 关于我
  • LINKS
  • ME
Claves
长风破浪会有时,直挂云帆济沧海
  1. 首页
  2. Programming
  3. Python
  4. 正文

Python之selectors模块

2022-06-04

官方文档:https://docs.python.org/3/library/selectors.html

参考链接:
https://www.cnblogs.com/zzzlw/p/9384308.html
https://blog.csdn.net/cswhl/article/details/111572702
基本介绍 https://www.cnblogs.com/yinheyi/p/8127871.html
实验演示 https://www.cnblogs.com/xybaby/p/6406191.html#_label_2
详细讲解 http://aju.space/2017/07/31/Drive-into-python-asyncio-programming-part-1.html
官方文档selecotors https://docs.python.org/3/library/selectors.html
官方文档select https://docs.python.org/3/library/select.html

IO模型:https://www.cnblogs.com/-wenli/p/10644511.html

selectors是一个python自带的高性能、IO复用模块,可以用来替代select模块。

测试代码:

#!/usr/bin/python3

import socket
from urllib.parse import urlparse
# DefaultSelector默认选择器,使用当前平台上可用的最高效的实现(select/poll/epoll)
from selectors import DefaultSelector, EVENT_READ, EVENT_WRITE


class Client(object):
    '''负责连接、 发送和接受'''
    def __init__(self, url):
        url = urlparse(url)
        self.host, self.path = url.netloc, [url.path, '/'][url.path == '']
        self.sock = socket.socket()
        self.sock.setblocking(False)
        self.data = b''
        try:
            self.sock.connect((self.host, 80))
        except BlockingIOError as ret:  # noqa
            pass

    def send_request(self):
        self.sock.send(
            "GET {} HTTP/1.1\r\nHost: {}\r\nConnection:close\r\n\r\n".format(
                self.path, self.host).encode('utf-8'))

    def recv_response(self):
        rev = self.sock.recv(1024)
        if rev:
            self.data += rev
            return True
        return False

    def end(self):
        html_body = self.data.split(b'\r\n\r\n')[1]
        self.sock.close()
        print(html_body)
        print('\n')
        return html_body


'''select + callback + eventLoop:单线程并发
只处理准备好socket事件,无需等待I/O;省去了线程切换的开销
回调模式:底层调用高层'''


class Select(object):
    '''创建selector,负责注册和取消注册socket读写事件、'''

    def __init__(self):
        self.selector = DefaultSelector()
        self.clients = {}

    def startListening(self, client):
        # add client,monitor socked wtite event
        self.clients[client.sock] = client
        # 注册socket写事件
        self.selector.register(client.sock, EVENT_WRITE, self.connected)

    def connected(self, key):
        # connect host,and monitor socket read event
        self.selector.unregister(key.fileobj)
        sock = key.fileobj
        self.clients[sock].send_request()
        self.selector.register(sock, EVENT_READ, self.do_read)

    def do_read(self, key):
        # read data ,if data is empty, then unregister socket and end
        sock = key.fileobj
        client = self.clients[sock]
        if client.recv_response():
            return
        self.selector.unregister(sock)
        client.end()


def event_loop():
    while True:
        events = sel.selector.select()
        for key, mask in events:
            print(key, mask)
            callback = key.data
            callback(key)


if __name__ == '__main__':
    urls = ['http://www.baidu.com', 'http://httpbin.org/']
    sel = Select()
    for url in urls:
        sel.startListening(Client(url))
    event_loop()
    sel.selector.close()

原理介绍:

标签: 暂无
最后更新:2022-06-04

代号山岳

知之为知之 不知为不知

点赞
< 上一篇
下一篇 >

COPYRIGHT © 2099 登峰造极境. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

蜀ICP备14031139号-5

川公网安备51012202000587号