为什么select.select()可以用于磁盘文件而epoll()不行?

8 投票
1 回答
3800 浏览
提问于 2025-04-17 09:05

下面的代码基本上是用select.select()来读取一个文件:

f = open('node.py')
fd = f.fileno()
while True:
    r, w, e = select.select([fd], [], [])
    print '>', repr(os.read(fd, 10))
    time.sleep(1)

但是当我用epoll做类似的事情时,就出现了错误:

self._impl.register(fd, events | self.ERROR)
IOError: [Errno 1] Operation not permitted 

我还听说epoll不支持磁盘文件——或者说这样做没有意义。

关于常规文件的epoll

那么,为什么select()却支持磁盘文件呢?我查看了selectmodule.c的实现,发现它似乎只是直接调用了操作系统,也就是说,Python并没有添加任何特别的支持。

从更高的层面来看,我正在尝试在一个非阻塞的服务器中找到最佳的静态文件服务方式。我想我会尝试创建一些I/O线程,从磁盘读取数据,然后把这些数据传给主事件循环线程,后者负责写入套接字。

1 个回答

9

select可以用来监控指向普通文件的文件描述符,但它总是会把文件报告为可读或可写的状态。也就是说,这个功能有点没用,因为它并不能告诉你实际进行读写操作时是否会被阻塞。

而epoll则不允许监控普通文件,因为在Linux系统上,它没有办法判断读写普通文件时是否会被阻塞。

撰写回答