tornado.ioloop — Main event loop¶
An I/O event loop for non-blocking sockets.
On Python 3, IOLoop is a wrapper around the asyncio event loop.
Typical applications will use a single IOLoop object, accessed via
IOLoop.current class method. The IOLoop.start method (or
equivalently, asyncio.AbstractEventLoop.run_forever) should usually
be called at the end of the main() function. Atypical applications
may use more than one IOLoop, such as one IOLoop per thread, or
per unittest case.
In addition to I/O events, the IOLoop can also schedule time-based
events. IOLoop.add_timeout is a non-blocking alternative to
time.sleep.
IOLoop objects¶
-
class
tornado.ioloop.IOLoop[源代码]¶ A level-triggered I/O loop.
On Python 3,
IOLoopis a wrapper around theasyncioevent loop. On Python 2, it usesepoll(Linux) orkqueue(BSD and Mac OS X) if they are available, or else we fall back on select(). If you are implementing a system that needs to handle thousands of simultaneous connections, you should use a system that supports eitherepollorkqueue.Example usage for a simple TCP server:
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 socket.error as e: if e.args[0] not in (errno.EWOULDBLOCK, errno.EAGAIN): raise return connection.setblocking(0) io_loop = tornado.ioloop.IOLoop.current() io_loop.spawn_callback(handle_connection, connection, address) if __name__ == '__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) io_loop.start()
By default, a newly-constructed
IOLoopbecomes the thread’s currentIOLoop, unless there already is a currentIOLoop. This behavior can be controlled with themake_currentargument to theIOLoopconstructor: ifmake_current=True, the newIOLoopwill always try to become current and it raises an error if there is already a current instance. Ifmake_current=False, the newIOLoopwill not try to become current.In general, an
IOLoopcannot survive a fork or be shared across processes in any way. When multiple processes are being used, each process should create its ownIOLoop, which also implies that any objects which depend on theIOLoop(such asAsyncHTTPClient) must also be created in the child processes. As a guideline, anything that starts processes (including thetornado.processandmultiprocessingmodules) should do so as early as possible, ideally the first thing the application does after loading its configuration inmain().在 4.2 版更改: Added the
make_currentkeyword argument to theIOLoopconstructor.
Running an IOLoop¶
-
static
IOLoop.current(instance=True)[源代码]¶ Returns the current thread’s
IOLoop.If an
IOLoopis currently running or has been marked as current bymake_current, returns that instance. If there is no currentIOLoopandinstanceis true, creates one.在 4.1 版更改: Added
instanceargument to control the fallback toIOLoop.instance().在 5.0 版更改: On Python 3, control of the current
IOLoopis delegated toasyncio, with this and other methods as pass-through accessors. Theinstanceargument now controls whether anIOLoopis created automatically when there is none, instead of whether we fall back toIOLoop.instance()(which is now an alias for this method).instance=Falseis deprecated, since even if we do not create anIOLoop, this method may initialize the asyncio loop.
-
IOLoop.make_current()[源代码]¶ Makes this the
IOLoopfor the current thread.An
IOLoopautomatically becomes current for its thread when it is started, but it is sometimes useful to callmake_currentexplicitly before starting theIOLoop, so that code run at startup time can find the right instance.在 5.0 版更改: This method also sets the current
asyncioevent loop.
-
static
IOLoop.clear_current()[源代码]¶ Clears the
IOLoopfor the current thread.Intended primarily for use by test frameworks in between tests.
在 5.0 版更改: This method also clears the current
asyncioevent loop.
-
IOLoop.start()[源代码]¶ Starts the I/O loop.
The loop will run until one of the callbacks calls
stop(), which will make the loop stop after the current event iteration completes.
-
IOLoop.stop()[源代码]¶ Stop the I/O loop.
If the event loop is not currently running, the next call to
start()will return immediately.Note that even after
stophas been called, theIOLoopis not completely stopped untilIOLoop.starthas also returned. Some work that was scheduled before the call tostopmay still be run before theIOLoopshuts down.
-
IOLoop.run_sync(func, timeout=None)[源代码]¶ Starts the
IOLoop, runs the given function, and stops the loop.The function must return either an awaitable object or
None. If the function returns an awaitable object, theIOLoopwill run until the awaitable is resolved (andrun_sync()will return the awaitable’s result). If it raises an exception, theIOLoopwill stop and the exception will be re-raised to the caller.The keyword-only argument
timeoutmay be used to set a maximum duration for the function. If the timeout expires, atornado.util.TimeoutErroris raised.This method is useful to allow asynchronous calls in a
main()function:async def main(): # do stuff... if __name__ == '__main__': IOLoop.current().run_sync(main)
在 4.3 版更改: Returning a non-
None, non-awaitable value is now an error.在 5.0 版更改: If a timeout occurs, the
funccoroutine will be cancelled.
-
IOLoop.close(all_fds=False)[源代码]¶ Closes the
IOLoop, freeing any resources used.If
all_fdsis true, all file descriptors registered on the IOLoop will be closed (not just the ones created by theIOLoopitself).Many applications will only use a single
IOLoopthat runs for the entire lifetime of the process. In that case closing theIOLoopis not necessary since everything will be cleaned up when the process exits.IOLoop.closeis provided mainly for scenarios such as unit tests, which create and destroy a large number ofIOLoops.An
IOLoopmust be completely stopped before it can be closed. This means thatIOLoop.stop()must be called andIOLoop.start()must be allowed to return before attempting to callIOLoop.close(). Therefore the call toclosewill usually appear just after the call tostartrather than near the call tostop.在 3.1 版更改: If the
IOLoopimplementation supports non-integer objects for “file descriptors”, those objects will have theirclosemethod whenall_fdsis true.
-
static
IOLoop.instance()[源代码]¶ Deprecated alias for
IOLoop.current().在 5.0 版更改: Previously, this method returned a global singleton
IOLoop, in contrast with the per-threadIOLoopreturned bycurrent(). In nearly all cases the two were the same (when they differed, it was generally used from non-Tornado threads to communicate back to the main thread’sIOLoop). This distinction is not present inasyncio, so in order to facilitate integration with that packageinstance()was changed to be an alias tocurrent(). Applications using the cross-thread communications aspect ofinstance()should instead set their own global variable to point to theIOLoopthey want to use.5.0 版后已移除.
-
IOLoop.install()[源代码]¶ Deprecated alias for
make_current().在 5.0 版更改: Previously, this method would set this
IOLoopas the global singleton used byIOLoop.instance(). Now thatinstance()is an alias forcurrent(),install()is an alias formake_current().5.0 版后已移除.
-
static
IOLoop.clear_instance()[源代码]¶ Deprecated alias for
clear_current().在 5.0 版更改: Previously, this method would clear the
IOLoopused as the global singleton byIOLoop.instance(). Now thatinstance()is an alias forcurrent(),clear_instance()is an alias forclear_current().5.0 版后已移除.
I/O events¶
-
IOLoop.add_handler(fd, handler, events)[源代码]¶ Registers the given handler to receive the given events for
fd.The
fdargument may either be an integer file descriptor or a file-like object with afileno()method (and optionally aclose()method, which may be called when theIOLoopis shut down).The
eventsargument is a bitwise or of the constantsIOLoop.READ,IOLoop.WRITE, andIOLoop.ERROR.When an event occurs,
handler(fd, events)will be run.在 4.0 版更改: Added the ability to pass file-like objects in addition to raw file descriptors.
Callbacks and timeouts¶
-
IOLoop.add_callback(callback, *args, **kwargs)[源代码]¶ Calls the given callback on the next I/O loop iteration.
It is safe to call this method from any thread at any time, except from a signal handler. Note that this is the only method in
IOLoopthat makes this thread-safety guarantee; all other interaction with theIOLoopmust be done from thatIOLoop’s thread.add_callback()may be used to transfer control from other threads to theIOLoop’s thread.To add a callback from a signal handler, see
add_callback_from_signal.
-
IOLoop.add_callback_from_signal(callback, *args, **kwargs)[源代码]¶ Calls the given callback on the next I/O loop iteration.
Safe for use from a Python signal handler; should not be used otherwise.
Callbacks added with this method will be run without any
stack_context, to avoid picking up the context of the function that was interrupted by the signal.
-
IOLoop.add_future(future, callback)[源代码]¶ Schedules a callback on the
IOLoopwhen the givenFutureis finished.The callback is invoked with one argument, the
Future.This method only accepts
Futureobjects and not other awaitables (unlike most of Tornado where the two are interchangeable).
-
IOLoop.add_timeout(deadline, callback, *args, **kwargs)[源代码]¶ Runs the
callbackat the timedeadlinefrom the I/O loop.Returns an opaque handle that may be passed to
remove_timeoutto cancel.deadlinemay be a number denoting a time (on the same scale asIOLoop.time, normallytime.time), or adatetime.timedeltaobject for a deadline relative to the current time. Since Tornado 4.0,call_lateris a more convenient alternative for the relative case since it does not require a timedelta object.Note that it is not safe to call
add_timeoutfrom other threads. Instead, you must useadd_callbackto transfer control to theIOLoop’s thread, and then calladd_timeoutfrom there.Subclasses of IOLoop must implement either
add_timeoutorcall_at; the default implementations of each will call the other.call_atis usually easier to implement, but subclasses that wish to maintain compatibility with Tornado versions prior to 4.0 must useadd_timeoutinstead.在 4.0 版更改: Now passes through
*argsand**kwargsto the callback.
-
IOLoop.call_at(when, callback, *args, **kwargs)[源代码]¶ Runs the
callbackat the absolute time designated bywhen.whenmust be a number using the same reference point asIOLoop.time.Returns an opaque handle that may be passed to
remove_timeoutto cancel. Note that unlike theasynciomethod of the same name, the returned object does not have acancel()method.See
add_timeoutfor comments on thread-safety and subclassing.4.0 新版功能.
-
IOLoop.call_later(delay, callback, *args, **kwargs)[源代码]¶ Runs the
callbackafterdelayseconds have passed.Returns an opaque handle that may be passed to
remove_timeoutto cancel. Note that unlike theasynciomethod of the same name, the returned object does not have acancel()method.See
add_timeoutfor comments on thread-safety and subclassing.4.0 新版功能.
-
IOLoop.remove_timeout(timeout)[源代码]¶ Cancels a pending timeout.
The argument is a handle as returned by
add_timeout. It is safe to callremove_timeouteven if the callback has already been run.
-
IOLoop.spawn_callback(callback, *args, **kwargs)[源代码]¶ Calls the given callback on the next IOLoop iteration.
Unlike all other callback-related methods on IOLoop,
spawn_callbackdoes not associate the callback with its caller’sstack_context, so it is suitable for fire-and-forget callbacks that should not interfere with the caller.4.0 新版功能.
-
IOLoop.run_in_executor(executor, func, *args)[源代码]¶ Runs a function in a
concurrent.futures.Executor. IfexecutorisNone, the IO loop’s default executor will be used.Use
functools.partialto pass keyword arguments tofunc.5.0 新版功能.
-
IOLoop.set_default_executor(executor)[源代码]¶ Sets the default executor to use with
run_in_executor().5.0 新版功能.
-
IOLoop.time()[源代码]¶ Returns the current time according to the
IOLoop’s clock.The return value is a floating-point number relative to an unspecified time in the past.
By default, the
IOLoop’s time function istime.time. However, it may be configured to use e.g.time.monotonicinstead. Calls toadd_timeoutthat pass a number instead of adatetime.timedeltashould use this function to compute the appropriate time, so they can work no matter what time function is chosen.
-
class
tornado.ioloop.PeriodicCallback(callback, callback_time, jitter=0)[源代码]¶ Schedules the given callback to be called periodically.
The callback is called every
callback_timemilliseconds. Note that the timeout is given in milliseconds, while most other time-related functions in Tornado use seconds.If
jitteris specified, each callback time will be randomly selected within a window ofjitter * callback_timemilliseconds. Jitter can be used to reduce alignment of events with similar periods. A jitter of 0.1 means allowing a 10% variation in callback time. The window is centered oncallback_timeso the total number of calls within a given interval should not be significantly affected by adding jitter.If the callback runs for longer than
callback_timemilliseconds, subsequent invocations will be skipped to get back on schedule.startmust be called after thePeriodicCallbackis created.在 5.0 版更改: The
io_loopargument (deprecated since version 4.1) has been removed.在 5.1 版更改: The
jitterargument is added.-
is_running()[源代码]¶ Return True if this
PeriodicCallbackhas been started.4.1 新版功能.
-
Debugging and error handling¶
-
IOLoop.handle_callback_exception(callback)[源代码]¶ This method is called whenever a callback run by the
IOLoopthrows an exception.By default simply logs the exception as an error. Subclasses may override this method to customize reporting of exceptions.
The exception itself is not passed explicitly, but is available in
sys.exc_info.
-
IOLoop.set_blocking_signal_threshold(seconds, action)[源代码]¶ Sends a signal if the
IOLoopis blocked for more thansseconds.Pass
seconds=Noneto disable. Requires Python 2.6 on a unixy platform.The action parameter is a Python signal handler. Read the documentation for the
signalmodule for more information. Ifactionis None, the process will be killed if it is blocked for too long.5.0 版后已移除: Not implemented on the
asyncioevent loop. Use the environment variablePYTHONASYNCIODEBUG=1instead. This method will be removed in Tornado 6.0.
-
IOLoop.set_blocking_log_threshold(seconds)[源代码]¶ Logs a stack trace if the
IOLoopis blocked for more thansseconds.Equivalent to
set_blocking_signal_threshold(seconds, self.log_stack)5.0 版后已移除: Not implemented on the
asyncioevent loop. Use the environment variablePYTHONASYNCIODEBUG=1instead. This method will be removed in Tornado 6.0.
-
IOLoop.log_stack(signal, frame)[源代码]¶ Signal handler to log the stack trace of the current thread.
For use with
set_blocking_signal_threshold.5.1 版后已移除: This method will be removed in Tornado 6.0.
Methods for subclasses¶
-
IOLoop.close_fd(fd)[源代码]¶ Utility method to close an
fd.If
fdis a file-like object, we close it directly; otherwise we useos.close.This method is provided for use by
IOLoopsubclasses (in implementations ofIOLoop.close(all_fds=True)and should not generally be used by application code.4.0 新版功能.
-
IOLoop.split_fd(fd)[源代码]¶ Returns an (fd, obj) pair from an
fdparameter.We accept both raw file descriptors and file-like objects as input to
add_handlerand related methods. When a file-like object is passed, we must retain the object itself so we can close it correctly when theIOLoopshuts down, but the poller interfaces favor file descriptors (they will accept file-like objects and callfileno()for you, but they always return the descriptor itself).This method is provided for use by
IOLoopsubclasses and should not generally be used by application code.4.0 新版功能.