tornado.ioloop ---主事件循环¶
用于非阻塞套接字的I/O事件循环。
在 Tornado 6号, IOLoop 是一个包装 asyncio 事件循环,由于历史原因,接口略有不同。应用程序可以使用 IOLoop 接口或底层 asyncio 直接事件循环(除非需要与旧版Tornado兼容,在这种情况下 IOLoop 必须使用。
典型应用将使用一个 IOLoop 对象,通过访问 IOLoop.current 类方法。这个 IOLoop.start 方法(或同等方法, asyncio.AbstractEventLoop.run_forever )通常应在 main() 功能。非典型应用程序可以使用多个 IOLoop ,比如一 IOLoop 每个线程,或每个 unittest 案例。
IOOOP对象¶
- class tornado.ioloop.IOLoop(*args: Any, **kwargs: Any)[源代码]¶
I/O事件循环。
从 Tornado 6.0开始,
IOLoop是一个包装asyncio事件循环。简单TCP服务器的示例用法:
import asyncio import errno import functools import socket import tornado.ioloop from tornado.iostream import IOStream async def handle_connection(connection, address): stream = IOStream(connection) message = await stream.read_until_close() print("message from client:", message.decode().strip()) def connection_ready(sock, fd, events): while True: try: connection, address = sock.accept() except BlockingIOError: return connection.setblocking(0) io_loop = tornado.ioloop.IOLoop.current() io_loop.spawn_callback(handle_connection, connection, address) async def main(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setblocking(0) sock.bind(("", 8888)) sock.listen(128) io_loop = tornado.ioloop.IOLoop.current() callback = functools.partial(connection_ready, sock) io_loop.add_handler(sock.fileno(), callback, io_loop.READ) await asyncio.Event().wait() if __name__ == "__main__": asyncio.run(main())
不要试图构造一个
IOLoop直接;从Tornado 6.2开始就不再推荐使用该功能。相反,应初始化asyncio事件循环和使用IOLoop.current()要访问IOLoop包装当前事件循环。一般来说,一个
IOLoop不能在fork中生存,也不能以任何方式在进程间共享。当使用多个进程时,每个进程都应该创建自己的进程IOLoop也意味着任何依赖于IOLoop(如AsyncHTTPClient)还必须在子进程中创建。作为指导方针,启动流程的任何内容(包括tornado.process和multiprocessing模块)应该尽可能早地这样做,理想情况下,应用程序在加载其配置后要做的第一件事是main().在 4.2 版更改: 增加了
make_current关键字参数IOLoop建造师。6.2 版后已移除: 不建议创建“当前”但当前未运行的事件循环。这意味着它不推荐使用
make_current=True发送到IOLoop构造函数,或创建一个IOLoop而没有正在运行的异步事件循环,除非make_current=False是使用的。
运行IOLoop¶
- static IOLoop.current() IOLoop[源代码]¶
- static IOLoop.current(instance: bool = True) Optional[IOLoop]
返回当前线程的
IOLoop.如果一个
IOLoop当前正在运行或被标记为当前make_current,返回该实例。如果没有电流IOLoop和instance是真的,创造了一个。在 4.1 版更改: 补充
instance用于控制回退的参数IOLoop.instance().在 5.0 版更改: 在python 3上,控制当前
IOLoop委派给asyncio,使用此方法和其他方法作为传递访问器。这个instance参数现在控制IOLoop当没有时自动创建,而不是返回IOLoop.instance()(现在是此方法的别名)。instance=False已弃用,因为即使我们不创建IOLoop,此方法可以初始化Asyncio循环。6.2 版后已移除: 不推荐调用
IOLoop.current()当没有asyncio事件循环正在运行。
- IOLoop.make_current() None[源代码]¶
使这个
IOLoop对于当前线程。安
IOLoop当线程启动时自动变为当前线程,但有时调用make_current在启动IOLoop,以便在启动时运行的代码可以找到正确的实例。在 5.0 版更改: 此方法还设置当前
asyncio事件循环。6.2 版后已移除: 在从Python3.10开始的Asyncio中,不推荐使用“当前”而不是当前正在运行的事件循环的概念。Tornado中的所有相关功能也已弃用。相反,使用以下命令开始事件循环
asyncio.run在与它互动之前。
- static IOLoop.clear_current() None[源代码]¶
清除
IOLoop对于当前线程。主要供测试框架在测试之间使用。
在 5.0 版更改: 此方法还清除当前
asyncio事件循环。6.2 版后已移除.
- IOLoop.stop() None[源代码]¶
停止I/O循环。
如果事件循环当前未运行,则下次调用
start()将立即返回。注意,即使在
stop被称为IOLoop直到IOLoop.start也已返回。在呼叫之前安排的一些工作stop可能仍在运行之前IOLoop关闭。
- IOLoop.run_sync(func: Callable, timeout: Optional[float] = None) Any[源代码]¶
开始
IOLoop,运行给定的函数,并停止循环。函数必须返回可等待的对象或
None. 如果函数返回一个可等待的对象,IOLoop将一直运行,直到等待解决(和run_sync()将返回等待的结果)。如果它引发了一个异常,IOLoop将停止并向调用方重新引发异常。仅限关键字的参数
timeout可用于设置功能的最大持续时间。如果超时到期,则会引发asyncio.TimeoutError都被养大了。此方法对于允许在
main()功能:async def main(): # do stuff... if __name__ == '__main__': IOLoop.current().run_sync(main)
在 4.3 版更改: 返回一个非``无`,不可等待的值现在是一个错误。
在 5.0 版更改: 如果发生超时,则
func协程将取消。在 6.2 版更改:
tornado.util.TimeoutError现在是的别名asyncio.TimeoutError。
- IOLoop.close(all_fds: bool = False) None[源代码]¶
关闭
IOLoop,释放所有使用的资源。如果
all_fds如果为真,则将关闭在IOLoop上注册的所有文件描述符(而不仅仅是由IOLoop本身)。许多应用程序将只使用一个
IOLoop在整个进程的生命周期中运行。在这种情况下,关闭IOLoop不需要,因为当进程退出时,所有内容都将被清除。IOLoop.close主要用于单元测试等场景,这些场景创建和销毁大量IOLoops.安
IOLoop必须完全停止才能关闭。这意味着IOLoop.stop()必须被称为 andIOLoop.start()必须允许返回才能尝试调用IOLoop.close(). 因此呼吁close通常会在呼叫后出现start而不是在电话附近stop.在 3.1 版更改: 如果
IOLoop实现支持“文件描述符”的非整数对象,这些对象将具有close方法时all_fds是真的。
- static IOLoop.instance() tornado.ioloop.IOLoop[源代码]¶
的别名已弃用
IOLoop.current().在 5.0 版更改: 在此之前,此方法返回了全局单例
IOLoop与每根线形成对比IOLoop返回的current(). 在几乎所有的情况下,这两个线程都是相同的(当它们不同时,通常使用非Tornado线程来与主线程的IOLoop)这种区别不存在于asyncio,因此为了便于与该包集成instance()已更改为别名current(). 使用跨线程通信方面的应用程序instance()应该改为将自己的全局变量设置为指向IOLoop他们想用。5.0 版后已移除.
- IOLoop.install() None[源代码]¶
的别名已弃用
make_current().在 5.0 版更改: 在此之前,此方法将设置
IOLoop作为IOLoop.instance(). 既然instance()是一个别名current(),install()是一个别名make_current().5.0 版后已移除.
- static IOLoop.clear_instance() None[源代码]¶
的别名已弃用
clear_current().在 5.0 版更改: 在此之前,此方法将清除
IOLoop用作全局单例IOLoop.instance(). 既然instance()是一个别名current(),clear_instance()是一个别名clear_current().5.0 版后已移除.
输入输出事件¶
- IOLoop.add_handler(fd: int, handler: Callable[[int, int], None], events: int) None[源代码]¶
- IOLoop.add_handler(fd: tornado.ioloop._S, handler: Callable[[tornado.ioloop._S, int], None], events: int) None
注册给定的处理程序以接收
fd.这个
fd参数可以是一个整型文件描述符,也可以是一个具有fileno()和close()方法。这个
events参数是常量的位或IOLoop.READ,IOLoop.WRITE和IOLoop.ERROR.当事件发生时,
handler(fd, events)将运行。在 4.0 版更改: 除了原始文件描述符之外,还增加了传递类似文件的对象的能力。
回调和超时¶
- IOLoop.add_callback(callback: Callable, *args: Any, **kwargs: Any) None[源代码]¶
在下一个I/O循环迭代中调用给定的回调。
在任何时候从任何线程调用此方法都是安全的,信号处理程序除外。注意这是 only 方法在
IOLoop这使得线程的安全性得到保证;与IOLoop必须从那开始IOLoop的线索。add_callback()可用于将控制从其他线程传输到IOLoop的线索。要从信号处理程序添加回调,请参见
add_callback_from_signal.
- IOLoop.add_callback_from_signal(callback: Callable, *args: Any, **kwargs: Any) None[源代码]¶
在下一个I/O循环迭代中调用给定的回调。
可以从python信号处理程序安全地使用;否则不应使用。
- IOLoop.add_future(future: Union[Future[_T], concurrent.futures.Future[_T]], callback: Callable[[Future[_T]], None]) None[源代码]¶
在上调度回调
IOLoop当给定Future完成了。调用回调时使用一个参数,即
Future.此方法只接受
Future物体而不是其他等待物(不像 Tornado 中的大多数,两者可以互换)。
- IOLoop.add_timeout(deadline: Union[float, datetime.timedelta], callback: Callable, *args: Any, **kwargs: Any) object[源代码]¶
运行
callback当时deadline从I/O循环。返回可传递给
remove_timeout取消。deadline可以是表示时间的数字(与IOLoop.time,正常情况下time.time)datetime.timedelta对象,用于相对于当前时间的截止时间。自从 Tornado 4.0以来,call_later对于相对情况来说是一个更方便的选择,因为它不需要TimeDelta对象。注意打电话不安全
add_timeout从其他线程。相反,你必须使用add_callback将控制权转移到IOLoop的线程,然后调用add_timeout从那里。IOLoop的子类必须实现
add_timeout或call_at;每个的默认实现将调用另一个。call_at通常更容易实现,但希望与4.0之前的Tornado版本保持兼容性的子类必须使用add_timeout相反。在 4.0 版更改: 现在通过
*args和**kwargs回拨电话。
- IOLoop.call_at(when: float, callback: Callable, *args: Any, **kwargs: Any) object[源代码]¶
运行
callback在指定的绝对时间when.when必须是使用与相同参考点的数字IOLoop.time.返回可传递给
remove_timeout取消。注意,与asyncio方法的名称相同,返回的对象没有cancel()方法。见
add_timeout有关线程安全和子类化的注释。4.0 新版功能.
- IOLoop.call_later(delay: float, callback: Callable, *args: Any, **kwargs: Any) object[源代码]¶
运行
callback之后delay几秒钟过去了。返回可传递给
remove_timeout取消。注意,与asyncio方法的名称相同,返回的对象没有cancel()方法。见
add_timeout有关线程安全和子类化的注释。4.0 新版功能.
- IOLoop.remove_timeout(timeout: object) None[源代码]¶
取消挂起的超时。
参数是由返回的句柄
add_timeout. 打电话是安全的remove_timeout即使回调已经运行。
- IOLoop.spawn_callback(callback: Callable, *args: Any, **kwargs: Any) None[源代码]¶
在下一个IOLoop迭代中调用给定的回调。
从Tornado 6.0开始,该方法相当于
add_callback.4.0 新版功能.
- IOLoop.run_in_executor(executor: Optional[concurrent.futures._base.Executor], func: Callable[[...], tornado.ioloop._T], *args: Any) Awaitable[tornado.ioloop._T][源代码]¶
在中运行函数
concurrent.futures.Executor.如果executor是None,将使用IO循环的默认执行器。使用
functools.partial将关键字参数传递给func.5.0 新版功能.
- IOLoop.set_default_executor(executor: concurrent.futures._base.Executor) None[源代码]¶
设置与一起使用的默认执行器
run_in_executor().5.0 新版功能.
- IOLoop.time() float[源代码]¶
根据返回当前时间
IOLoop钟。返回值是相对于过去未指定时间的浮点数。
历史上,IOLoop可以定制为使用例如
time.monotonic而不是time.time,但当前不支持此方法,因此此方法等效于time.time.
- class tornado.ioloop.PeriodicCallback(callback: Callable[[], Optional[Awaitable]], callback_time: Union[datetime.timedelta, float], jitter: float = 0)[源代码]¶
安排定期调用给定的回调。
回调调用的频率为
callback_time毫秒时callback_time是一个浮点。请注意,超时以毫秒为单位,而Tornado中的大多数其他与时间相关的函数使用秒。callback_time也可以作为datetime.timedelta对象。如果
jitter如果指定,则每个回调时间将在jitter * callback_time毫秒。抖动可用于减少具有类似周期的事件的对齐。抖动0.1意味着允许回拨时间有10%的变化。窗口居中callback_time因此,给定间隔内的调用总数不应受到添加抖动的显著影响。如果回调运行时间超过
callback_time毫秒,随后的调用将被跳过以恢复计划。start必须在PeriodicCallback创建。在 5.0 版更改: 这个
io_loop已删除参数(自4.1版以来已弃用)。在 5.1 版更改: 这个
jitter参数已添加。在 6.2 版更改: 如果
callback参数是协程,并且回调运行的时间长于callback_time,后续调用将被跳过。以前,这只适用于常规函数,而不适用于协程,因为协程对于以下对象是“即发即忘”的PeriodicCallback。- is_running() bool[源代码]¶
返回
True如果这样PeriodicCallback已启动。4.1 新版功能.