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

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中文词频统计

    一文带你掌握Python中文词频统计 介绍 针对中文的文本数据进行分析,通常需要进行中文分词以及词频统计。本文将通过Python编程实现中文词频统计的完整攻略。 分词工具 常用的分词工具有jieba、pkuseg等。本文以jieba作为分词工具 import jieba text = "今天是个好日子,天气非常的好" seg_list =…

    python 2023年5月13日
    00
  • python中wheel的用法整理

    Python中wheel的用法整理 概述 Python的wheel是一个二进制分发格式,它允许您将软件包编译为本机代码,并且安装起来比源代码更快。Wheel还提供了一种便捷的方式来构建Python软件包,即使您的软件包中包含C扩展也能有很好的表现。 在本篇文章中,我们将讲解一些使用wheel的常见场景和方法,以及如何使用pip安装和管理wheel包。这些应该…

    python 2023年5月14日
    00
  • Python concurrent.futures模块使用实例

    Python concurrent.futures模块使用实例 介绍 Python中的 concurrent.futures 模块提供了高级的异步编程接口,允许您在不需要显式地管理线程或进程的情况下编写并发代码。 该模块提供了 ThreadPoolExecutor 和 ProcessPoolExecutor 两个类,可以轻松地在多线程或多进程中执行函数。 安…

    python 2023年5月13日
    00
  • Python实现字典序列ChainMap

    Python的ChainMap类是一个非常有用的数据结构,可以让多个字典按照顺序合并成为一个字典,可以在这个新字典中进行键值查找和修改操作。简单来说,ChainMap会按照顺序查找多个字典,并返回最先找到的键值对。 具体步骤如下: 导入ChainMap类 from collections import ChainMap 创建多个字典 dict_1 = {‘a…

    python 2023年5月13日
    00
  • Python 推导式、生成器与切片问题解决思路

    Python 推导式、生成器与切片是Python编程中非常常用的语法和技巧。以下是针对这些问题的完整攻略: Python 推导式 Python 推导式是一种快速生成数据结构的方法,包括列表推导式、字典推导式和集合推导式。它们的格式都比较类似,主要由两个部分组成:表达式和迭代器。其中,表达式是将迭代器中的元素进行操作的计算式子,而迭代器可以是列表、字典、集合等…

    python 2023年6月3日
    00
  • linux环境下的python安装过程图解(含setuptools)

    下面是针对“linux环境下的python安装过程图解(含setuptools)”的完整攻略。 准备工作 在安装Python前,需要确认当前系统上是否已安装Python。可以在Linux终端中输入下面的命令来检查: python –version 如果能输出Python的版本号,说明已经安装有Python了,可以跳过本文前面的安装Python的步骤。 如果…

    python 2023年5月14日
    00
  • pyspark 随机森林的实现

    下面我将为您详细讲解”pyspark 随机森林的实现”的完整攻略,并给出两条示例说明。 1. 随机森林简介 随机森林是一种集成学习方法,可用于分类和回归问题中。随机森林的核心是决策树,它会随机从样本中选取特征,并使用基尼指数或信息增益来选择最佳的分裂点。这些决策树会进行随机投票,最终的预测结果是投票结果的平均值。随机森林通过随机化的方式减少了单棵决策树的过拟…

    python 2023年6月3日
    00
  • Python线程之如何解决共享变量问题

    Python中的线程是可以共享内存的,这意味着多个线程可以同时访问和修改同一个变量。然而,这也带来了共享变量问题,在多个线程修改同一个变量时,可能会出现数据不一致的问题。因此,我们需要采取一些措施来解决这个问题。 下面是一些解决Python线程共享变量问题的攻略。 使用锁机制 锁机制是常用的解决Python线程共享变量问题的方法之一。一个锁对象同时只能被一个…

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