python系列之 - select

这篇博客介绍了Python中的异步I/O处理模型,特别是select系统调用的工作原理和限制。文章指出select在跨平台支持方面的优势,但也提到其最大文件描述符数量限制和随着描述符增多带来的性能问题。此外,文章还简要提及了与poll、epoll的比较,并给出了epoll的实现实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

I/O多路复用是在单线程模式下实现多线程的效果,实现一个多I/O并发的效果。

看一个简单socket例子:

import socket

SOCKET_FAMILY = socket.AF_INET
SOCKET_TYPE = socket.SOCK_STREAM

sockServer = socket.socket()
sockServer.bind(('0.0.0.0', 8888))
sockServer.listen(5)

while True:
    cliobj, addr = sockServer.accept()
    while True:
        recvdata = cliobj.recv(1024)
        if recvdata:
            print(recvdata.decode())
        else:
            cliobj.close()
            break

客户端:

import socket

socCli = socket.socket()
socCli.connect(('127.0.0.1', 8888))
while True:
    data = input("input str:")
    socCli.send(data.encode())
<br />
以上为一个简单的客户端发送一个输入信息给服务端的socket通信的实例,在以上的例子中,服务端是一个单线程、阻塞模式的。如何实现多客户端连接呢,我们可以使用多线程模式,这个当然没有问题。 使用多线程、阻塞socket来处理的话,代码会很直观,但是也会有不少缺陷。它很难确保线程共享资源没有问题。而且这种编程风格的程序在只有一个CPU的电脑上面效率更低。但如果一个用户开启的线程有限的情况下,比如1024个。当第1025个客户端连接是仍然会阻塞。
有没有一种比较好的方式呢,当然有,其一是使用异步socket。 这种socket只有在一些event触发时才会阻塞。相反,程序在异步socket上面执行一个动作,会立即被告知这个动作是否成功。程序会根据这个信 息决定怎么继续下面的操作由于异步socket是非阻塞的,就没有必要再来使用多线程。所有的工作都可以在一个线程中完成。这种单线程模式有它自己的挑 战,但可以成为很多方案不错的选择。它也可以结合多线程一起使用:单线程使用异步socket用于处理服务器的网络部分,多线程可以用来访问其他阻塞资 源,比如数据库。Linux的2.6内核有一系列机制来管理异 步socket,其中3个有对应的Python的API:select、poll和epoll。epoll和pool比select更好,因为 Python程序不需要检查每一个socket感兴趣的event。相反,它可以依赖操作系统来告诉它哪些socket可能有这些event。epoll 比pool更好,因为它不要求操作系统每次都去检查python程序需要的所有socket感兴趣的event。而是Linux在event发生的时候会 跟踪到,并在Python需要的时候返回一个列表。因此epoll对于大量(成千上万)并发socket连接,是更有效率和可扩展的机制

异步I/O处理模型


select最早于1983年出现在4.2BSD中,它通过一个select()系统调用来监视多个文件描述符的数组,当select()返回后,该数组中就绪的文件描述符便会被内核修改标志位,使得进程可以获得这些文件描述符从而进行后续的读写操作。
select目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点,事实上从现在看来,这也是它所剩不多的优点之一。
select的一个缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,不过可以通过修改宏定义甚至重新编译内核的方式提升这一限制。
另外,select()所维护的存储大量文件描述符的数据结构,随着文件描述符数量的增大,其复制的开销也线性增长。同时,由于网络响应时间的延迟使得大量TCP连接处于非活跃状态,但调用select()会对

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值