18.3. select - 等待I / O完成

This module provides access to the select() and poll() functions available in most operating systems, devpoll() available on Solaris and derivatives, epoll() available on Linux 2.5+ and kqueue() available on most BSD. 注意,在Windows上,它只适用于套接字;在其他操作系统上,它也适用于其他文件类型(特别是在Unix上,它在管道上工作)。它不能用于常规文件,以确定文件自上次读取以来是否已增长。

注意

selectors模块允许基于select模块原语构建的高级和高效的I / O复用。建议用户使用selectors模块,除非他们需要精确控制所使用的操作系统级原语。

模块定义如下:

exception select.error

已弃用的OSError别名。

在版本3.3中已更改: PEP 3151之后,此类被设为OSError的别名。

select.devpoll()

(仅在Solaris和衍生产品上受支持。返回/dev/poll轮询对象;有关devpoll对象支持的方法,请参阅下面的/dev/poll Polling Objects一节。

devpoll()对象链接到在实例化时允许的文件描述器的数量。如果你的程序减少这个值,devpoll()将失败。如果你的程序增加这个值,devpoll()可能返回一个不完整的活动文件列表描述器。

新文件描述器是non-inheritable

版本3.3中的新功能。

在版本3.4中更改:新文件描述器现在是不可继承的。

select.epoll(sizehint=-1, flags=0)

(仅在Linux 2.5.44及更高版本上受支持。)返回边沿轮询对象,可用作I / O事件的边沿或级别触发接口。sizehint已被弃用并完全被忽略。标志可以设置为EPOLL_CLOEXEC,这将导致在调用os.execve()时epoll描述器自动关闭。

有关epolling对象支持的方法,请参见下面的Edge and Level Trigger Polling (epoll) Objects部分。

epoll对象支持上下文管理协议:当在with语句中使用时,新文件描述器在块结束时自动关闭。

新文件描述器是non-inheritable

在版本3.3中已更改:添加了标志参数。

在版本3.4中已更改:添加了对with语句的支持。新文件描述器现在是不可继承的。

select.poll()

(不受所有操作系统支持。)返回一个轮询对象,它支持注册和取消注册文件描述器,然后轮询它们的I / O事件;有关轮询对象支持的方法,请参阅下面的Polling Objects部分。

select.kqueue()

(仅在BSD上支持。返回一个内核队列对象;有关kqueue对象支持的方法,请参阅下面的Kqueue Objects部分。

新文件描述器是non-inheritable

在版本3.4中更改:新文件描述器现在是不可继承的。

select.kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)

(仅在BSD上支持。返回内核事件对象;有关kevent对象支持的方法,请参阅下面的Kevent Objects部分。

select.select(rlist, wlist, xlist[, timeout])

这是Unix select()系统调用的简单接口。前三个参数是“等待对象”的序列:使用名为fileno()的无参数方法表示文件描述器或对象的整数返回这样一个整数:

  • rlist:等待准备读取
  • wlist:等待准备写入
  • xlist:等待“异常条件”(请参阅​​系统认为此类条件的手册页)

允许空序列,但三个空序列的接受是平台依赖性的。(已知在Unix上工作,但在Windows上不工作。)可选的timeout参数将超时指定为浮点数,以秒为单位。当省略timeout参数时,该功能阻塞,直到至少一个文件描述器准备就绪。超时值零指定轮询并从不阻止。

返回值是准备好的对象列表的三倍:前三个参数的子集。当超时到达没有文件描述器变为准备好时,返回三个空列表。

在序列中可接受的对象类型中有Python file objects(例如,sys.stdin或由open()os.popen()返回的对象,socket.socket()你也可以自己定义一个wrapper类,只要它有一个适当的fileno()方法(真的返回一个文件描述器,而不只是一个随机整数)。

注意

Windows上的文件对象不可接受,但套接字是。在Windows上,底层的select()函数由WinSock库提供,不处理不是源自WinSock的文件描述器。

Changed in version 3.5: The function is now retried with a recomputed timeout when interrupted by a signal, except if the signal handler raises an exception (see PEP 475 for the rationale), instead of raising InterruptedError.

select.PIPE_BUF

当管道已报告为准备写入select()poll()或另一个接口时,可以写入的最小字节数而不会阻塞到管道这个模块。这不适用于其他类型的文件状对象,如套接字。

此值由POSIX保证至少为512。可用性:Unix。

版本3.2中的新功能。

18.3.1. /dev/poll Polling Objects

Solaris和衍生产品具有/dev/pollselect()是O(最高文件描述器),poll()是O(文件描述器的数目),/dev/poll

/dev/poll行为非常接近标准poll()对象。

devpoll.close()

关闭轮询对象的描述器。

版本3.4中的新功能。

devpoll.closed

True如果轮询对象已关闭。

版本3.4中的新功能。

devpoll.fileno()

返回轮询对象的描述器号。

版本3.4中的新功能。

devpoll.register(fd[, eventmask])

注册文件描述器与轮询对象。poll()方法的未来调用将检查文件描述器是否有任何未决的I / O事件。fd可以是整数,也可以是返回整数的fileno()方法的对象。文件对象实现fileno(),因此它们也可以用作参数。

eventmask是描述要检查的事件类型的可选位掩码。这些常量与poll()对象的常量相同。默认值是常量POLLINPOLLPRIPOLLOUT的组合。

警告

注册文件已经注册的描述器不是错误,但结果是未定义的。相应的操作是首先取消注册或修改它。poll()相比,这是一个重要的区别。

devpoll.modify(fd[, eventmask])

此方法执行unregister()后跟register()它是(有点)更有效率做同样明确。

devpoll.unregister(fd)

删除文件描述正在被轮询对象跟踪的器件。register()方法一样,fd可以是一个整数,也可以是一个返回整数的fileno()方法的对象。

尝试删除文件安全地忽略从未注册的描述器。

devpoll.poll([timeout])

调用注册文件描述器的集合,并返回一个包含(fd, 事件)有报告的事件或错误。fd是文件描述器,事件是一个位掩码,该位掩码为该描述器 - POLLIN POLLOUT以指示可以将描述器写入等等。空列表指示呼叫超时,并且没有文件描述器具有要报告的任何事件。如果给定timeout,则指定系统在返回之前等待事件的时间长度(以毫秒为单位)。如果省略timeout,-1或None,则调用将阻塞,直到此poll对象有事件为止。

Changed in version 3.5: The function is now retried with a recomputed timeout when interrupted by a signal, except if the signal handler raises an exception (see PEP 475 for the rationale), instead of raising InterruptedError.

18.3.2. Edge and Level Trigger Polling (epoll) Objects

http://linux.die.net/man/4/epoll

eventmask

Constant Meaning
EPOLLIN Available for read
EPOLLOUT Available for write
EPOLLPRI Urgent data for read
EPOLLERR Error condition happened on the assoc. fd
EPOLLHUP Hang up happened on the assoc. fd
EPOLLET Set Edge Trigger behavior, the default is Level Trigger behavior
EPOLLONESHOT Set one-shot behavior. After one event is pulled out, the fd is internally disabled
EPOLLRDNORM Equivalent to EPOLLIN
EPOLLRDBAND Priority data band can be read.
EPOLLWRNORM Equivalent to EPOLLOUT
EPOLLWRBAND Priority data may be written.
EPOLLMSG Ignored.
epoll.close()

关闭epoll对象的控制文件描述器。

epoll.closed

True如果epoll对象已关闭。

epoll.fileno()

返回文件描述fd的控件编号。

epoll.fromfd(fd)

从给定文件创建epoll对象描述器。

epoll.register(fd[, eventmask])

使用epoll对象注册fd描述器。

epoll.modify(fd, eventmask)

修改注册文件描述器。

epoll.unregister(fd)

删除注册文件从epoll对象中描述器件。

epoll.poll(timeout=-1, maxevents=-1)

等待事件。超时秒(float)

Changed in version 3.5: The function is now retried with a recomputed timeout when interrupted by a signal, except if the signal handler raises an exception (see PEP 475 for the rationale), instead of raising InterruptedError.

18.3.3. Polling Objects

在大多数Unix系统上支持的poll()系统调用为同时为许多客户端提供服务的网络服务器提供了更好的可扩展性。poll()更好,因为系统调用只需要列出感兴趣的文件描述器,而select()构建位图,打开感兴趣的fds的位,然后之后必须再次线性扫描整个位图。select()是O(最高文件描述器),而poll()是O(文件描述器的数目)。

poll.register(fd[, eventmask])

注册文件描述器与轮询对象。poll()方法的未来调用将检查文件描述器是否有任何未决的I / O事件。fd可以是整数,也可以是返回整数的fileno()方法的对象。文件对象实现fileno(),因此它们也可以用作参数。

eventmask是描述要检查的事件类型的可选位掩码,可以是常量POLLINPOLLPRIPOLLOUT,如下表所述。如果未指定,则使用的默认值将检查所有3种类型的事件。

不变含义
POLLIN有要读取的数据
POLLPRI有紧急数据要读
POLLOUT准备输出:写入不会阻塞
POLLERR某种类型的错误条件
POLLHUP挂了
POLLNVAL请求无效:描述器不打开

注册文件已经注册的描述器不是错误,并且与注册描述器完全一样的效果。

poll.modify(fd, eventmask)

修改已注册的fd。这与寄存器(fd, eventmask)具有相同的效果。尝试修改未曾注册的文件描述器会导致引发具有errno ENOENTOSError异常。

poll.unregister(fd)

删除文件描述正在被轮询对象跟踪的器件。register()方法一样,fd可以是一个整数或一个带有返回整数的fileno()方法的对象。

尝试删除文件描述未曾注册的器件会引发KeyError异常。

poll.poll([timeout])

调用注册文件描述器的集合,并返回一个包含(fd, 事件)有报告的事件或错误。fd是文件描述器,事件是一个位掩码,该位掩码为该描述器 - POLLIN POLLOUT以指示可以将描述器写入等等。空列表指示呼叫超时,并且没有文件描述器具有要报告的任何事件。如果给定timeout,则指定系统在返回之前等待事件的时间长度(以毫秒为单位)。如果省略超时,否定或None,调用将阻塞,直到此轮询对象有事件。

Changed in version 3.5: The function is now retried with a recomputed timeout when interrupted by a signal, except if the signal handler raises an exception (see PEP 475 for the rationale), instead of raising InterruptedError.

18.3.4. Kqueue Objects

kqueue.close()

关闭kqueue对象的控制文件描述器。

kqueue.closed

True如果kqueue对象关闭。

kqueue.fileno()

返回文件描述fd的控件编号。

kqueue.fromfd(fd)

从给定的文件创建一个kqueue对象描述器。

kqueue.control(changelist, max_events[, timeout=None]) → eventlist

低级别接口kevent

  • changelist必须是一个可迭代的kevent对象或None
  • max_events必须为0或正整数
  • 超时秒(可能是浮动)

Changed in version 3.5: The function is now retried with a recomputed timeout when interrupted by a signal, except if the signal handler raises an exception (see PEP 475 for the rationale), instead of raising InterruptedError.

18.3.5. Kevent Objects

https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2

kevent.ident

用于标识事件的值。解释取决于过滤器,但它通常是文件描述器。在构造函数中,ident可以是一个int或一个具有fileno()方法的对象。kevent内部存储整数。

kevent.filter

内核过滤器的名称。

不变含义
KQ_FILTER_READ使用描述器,并在有可用数据可读时返回
KQ_FILTER_WRITE使用描述器,并在有可用数据可写时返回
KQ_FILTER_AIOAIO请求
KQ_FILTER_VNODE发生在fflag中观看的一个或多个请求的事件时返回
KQ_FILTER_PROC监视进程标识上的事件
KQ_FILTER_NETDEV监视网络设备上的事件[Mac OS X上不可用]
KQ_FILTER_SIGNAL当监视信号传递到进程时返回
KQ_FILTER_TIMER建立任意定时器
kevent.flags

过滤操作。

不变含义
KQ_EV_ADD添加或修改事件
KQ_EV_DELETE从队列中删除事件
KQ_EV_ENABLEPermitcontrol()返回事件
KQ_EV_DISABLE禁用事件
KQ_EV_ONESHOT在第一次发生后删除事件
KQ_EV_CLEAR检索事件后重置状态
KQ_EV_SYSFLAGS内部事件
KQ_EV_FLAG1内部事件
KQ_EV_EOF过滤特定的EOF条件
KQ_EV_ERROR请参阅返回值
kevent.fflags

过滤特定标志。

KQ_FILTER_READKQ_FILTER_WRITE过滤器标记:

不变含义
KQ_NOTE_LOWAT低水位标记的套接字缓冲区

KQ_FILTER_VNODE过滤器标志:

不变含义
KQ_NOTE_DELETEunlink()被调用
KQ_NOTE_WRITE发生写操作
KQ_NOTE_EXTEND文件已扩展
KQ_NOTE_ATTRIB属性已更改
KQ_NOTE_LINK链接计数已更改
KQ_NOTE_RENAME该文件已重命名
KQ_NOTE_REVOKE对文件的访问被撤销

KQ_FILTER_PROC过滤器标志:

不变含义
KQ_NOTE_EXIT该进程已退出
KQ_NOTE_FORK该进程调用了fork()
KQ_NOTE_EXEC该进程已经执行了一个新的进程
KQ_NOTE_PCTRLMASK内部过滤器标志
KQ_NOTE_PDATAMASK内部过滤器标志
KQ_NOTE_TRACK通过fork()跟踪流程
KQ_NOTE_CHILDNOTE_TRACK的子进程上返回
KQ_NOTE_TRACKERR无法附加到孩子

KQ_FILTER_NETDEV过滤器标记(Mac OS X上不可用):

不变含义
KQ_NOTE_LINKUP链接起来
KQ_NOTE_LINKDOWN链接已关闭
KQ_NOTE_LINKINV链路状态无效
kevent.data

过滤特定数据。

kevent.udata

用户定义的值。