Python多路复用selector模块的基本使用

yizhihongxing

Python中的selector模块(selectors)为网络编程提供了非常方便的异步I/O解决方案,可以用来解决I/O操作的阻塞问题。

什么是Python多路复用selector模块?

在Python的标准库中,有一个selectors模块(在Python3中),这个模块提供了一种用于多路复用的支持,能够基于select、epoll、kqueue等系统调用实现I/O多路复用。

selector可以同时监控多个socket的可读、可写、错误状态,并且比起其他的多路复用模块来说更易于使用和控制。selectors在事件驱动模型中起到了非常重要的作用。

如何使用Python多路复用selector模块?

下面演示一下简单的使用控制台来多路复用监控多个socket的连接状态(读/写/异常)。

创建selector对象

创建selector对象之前,我们需要确认当前操作系统支持的多路复用模型,具体的模型与系统有关,常见的包括select、epoll、kqueue等模型。在Python标准库selectors中,可以根据需要自动选择具体的模型,这样就能够减轻可移植性的担忧。

import selectors

sel = selectors.DefaultSelector()

注册和取消注册事件

我们也可以将之前建立连接的socket对象跟selector对象绑定起来,注册事件监控。

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('example.com', 80))

sel.register(sock, selectors.EVENT_READ, data=None)

绑定事件就是将socket对象、事件类型、附加数据一起封装成Event对象,通过register()方法将Event对象提交给selector对象。

需要注意的是,如果一个socket对象已经被注册,又希望修改对这个socket对象监听的事件,则需要先使用 unregister() 方法将之前的绑定事件取消。

sel.unregister(sock)

开始事件循环

接下来,我们需要遍历从select()方法返回的所有事件(Event)并根据事件类型执行不同的操作。

while True:
    events = sel.select()
    for key, mask in events:
        sock = key.fileobj
        if mask & selectors.EVENT_READ:
            # data = sock.recv()
            pass
        if mask & selectors.EVENT_WRITE:
            # sock.send(data)
            pass

示例1:多路复用监控http请求

以下示例代码演示了如何使用selector多路复用监控http请求:

import selectors
import socket

host = 'www.baidu.com'
port = 80
data = "GET / HTTP/1.1\r\nHost: %s\r\n\r\n" % host

sel = selectors.DefaultSelector()

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setblocking(False)
sock.connect((host, port))

events = selectors.EVENT_READ | selectors.EVENT_WRITE
sel.register(sock, events)

try:
    while True:
        events = sel.select(timeout=1)
        if not events:
            continue

        for key, mask in events:
            sock = key.fileobj
            if mask & selectors.EVENT_WRITE:
                sent = sock.send(data.encode('utf-8'))
                sel.modify(sock, selectors.EVENT_READ)

            elif mask & selectors.EVENT_READ:
                received = sock.recv(1024)
                if received:
                    print(received.decode('utf-8'))
                sel.close()
                break

        break

finally:
    sel.close()

示例2:监控多个连接并同时处理请求

以下示例代码演示了如何使用selector同时监控多个socket连接的状态,并实现同时处理请求:

import selectors
import socket

host = '127.0.0.1'
port = 9090

sel = selectors.DefaultSelector()

def accept(sock):
    conn, addr = sock.accept()
    print('connected to:', addr)
    conn.setblocking(False)
    sel.register(conn, selectors.EVENT_READ, read)

def read(conn):
    data = conn.recv(1024)
    if not data:
        sel.unregister(conn)
        conn.close()
        return
    print(data.decode('utf-8'))
    conn.sendall(data)

sock = socket.socket()
sock.bind((host, port))
sock.listen(5)
sock.setblocking(False)

sel.register(sock, selectors.EVENT_READ, accept)

while True:
    event_list = sel.select()
    for key, mask in event_list:
        callback = key.data
        sock = key.fileobj
        callback(sock)

总结

通过使用selector模块,我们可以实现控制对多个socket连接的状态,以及实现回调函数的功能,将所有的socket对象汇集到一个事件循环中,通过select()系统调用来等待数据到来,以实现非阻塞的I/O多路复用。这样就可以大大提高网络编程效率,并且利用callback函数和当期Python版本的asyncore模块,也可以实现高效的异步I/O编程。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python多路复用selector模块的基本使用 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • Python语言实现百度语音识别API的使用实例

    Python语言实现百度语音识别API的使用实例 简介 百度语音识别API是一种可以实现将语音转换成文字的工具,它可以帮助我们解决语音转文本的问题。在这个攻略中,我们将详细介绍如何使用Python语言实现百度语音识别API的使用,并提供两个示例说明,帮助大家更好地理解API的使用方法。 准备条件 在开始使用API之前,我们需要先进行一些准备工作: 首先,我们…

    python 2023年5月19日
    00
  • python获取酷狗音乐top500的下载地址 MP3格式

    获取酷狗音乐top500的下载地址MP3格式,可以通过Python的爬虫技术实现。本攻略将介绍如何使用Python爬虫获取酷狗音乐top500的下载地址MP3格式,包括获取酷狗音乐top500的歌曲列表、获取酷狗音乐top500的歌曲下载地址、下载酷狗音乐top500的歌曲等。 步骤1:获取酷狗音乐top500的歌曲列表 首先,我们需要获取酷狗音乐top50…

    python 2023年5月15日
    00
  • Python异常 ValueError的问题

    Python异常ValueError的问题攻略 在Python编程中,我们经常会遇到ValueError异常。这个异常通常是由于传递给函数的参数类型不正确或参数值不在函数预期范内引起的。本攻略将介绍如何解决ValueError异常,并提供两个示例。 解决方法 在解决ValueError异常,我们可以尝试以下方法: 检查参数类型和值 使用try-except语…

    python 2023年5月13日
    00
  • python2使用bs4爬取腾讯社招过程解析

    由于Python2已经不再维护,建议使用Python3进行爬虫开发。不过,如果您仍然需要使用Python2进行爬虫开发,可以使用BeautifulSoup4(bs4)库进行网页解析。以下是详细讲解Python2使用bs4爬取腾讯社招过程解析的攻略,包含两个例。 示例1:使用bs4解析HTML页面 以下是一个示例,可以使用bs4解析HTML页面: import…

    python 2023年5月15日
    00
  • matplotlib画图之修改坐标轴刻度问题

    下面是关于“matplotlib画图之修改坐标轴刻度问题”的完整攻略。 修改坐标轴刻度问题 在使用Matplotlib进行可视化绘制时,我们可能会遇到需要修改坐标轴刻度的需求,比如想要自定义坐标轴上的刻度大小、标签内容或者刻度间隔等等。下面将给出两条示例,分别介绍如何实现这些操作。 示例一:自定义坐标轴刻度大小和标签 在Matplotlib中,默认的坐标轴刻…

    python 2023年5月18日
    00
  • python3.8.3安装教程及环境配置的详细教程(64-bit)

    下面是关于Python 3.8.3安装及环境配置的详细教程。 Python 3.8.3安装教程及环境配置的详细教程(64-bit) 1. 下载Python3.8.3 访问官方网站:https://www.python.org/downloads/release/python-383/,根据你的操作系统,选择64位的安装包下载。 选择“Python 3.8.3…

    python 2023年5月14日
    00
  • Python中的CURL PycURL使用例子

    CURL是一个用于传输数据的工具和库,支持多种协议,包括HTTP、FTP、SMTP等。PycURL是一个Python库,它提供了对CURL的Python绑定,可以方便地使用CURL进行网络通信。本文将详细讲解如何使用Python中的CURLPycURL库,包括如何发送HTTP请求、如何设置请求头、如何处理响应等。 安装PycURL 在使用PycURL之前,我…

    python 2023年5月15日
    00
  • python中print格式化输出的问题

    当我们在Python中使用print()函数输出结果时,经常需要进行格式化输出,让输出的内容更直观,易于理解。本篇攻略将详细讲解有关Python中print格式化输出的问题。 基本格式化方式 Python中使用字符串格式化语法来格式化print()函数的输出信息。格式化语法使用%字符作为标记,后面跟着一个或多个格式化字符,用来控制输出信息的样式。 例如,我们…

    python 2023年6月5日
    00
合作推广
合作推广
分享本页
返回顶部