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, IOLoop is a wrapper around the asyncio event loop. On Python 2, it uses epoll (Linux) or kqueue (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 either epoll or kqueue.

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 IOLoop becomes the thread’s current IOLoop, unless there already is a current IOLoop. This behavior can be controlled with the make_current argument to the IOLoop constructor: if make_current=True, the new IOLoop will always try to become current and it raises an error if there is already a current instance. If make_current=False, the new IOLoop will not try to become current.

In general, an IOLoop cannot survive a fork or be shared across processes in any way. When multiple processes are being used, each process should create its own IOLoop, which also implies that any objects which depend on the IOLoop (such as AsyncHTTPClient) must also be created in the child processes. As a guideline, anything that starts processes (including the tornado.process and multiprocessing modules) should do so as early as possible, ideally the first thing the application does after loading its configuration in main().

在 4.2 版更改: Added the make_current keyword argument to the IOLoop constructor.

在 5.0 版更改: Uses the asyncio event loop by default. The IOLoop.configure method cannot be used on Python 3 except to redundantly specify the asyncio event loop.

Running an IOLoop

static IOLoop.current(instance=True)[源代码]

Returns the current thread’s IOLoop.

If an IOLoop is currently running or has been marked as current by make_current, returns that instance. If there is no current IOLoop and instance is true, creates one.

在 4.1 版更改: Added instance argument to control the fallback to IOLoop.instance().

在 5.0 版更改: On Python 3, control of the current IOLoop is delegated to asyncio, with this and other methods as pass-through accessors. The instance argument now controls whether an IOLoop is created automatically when there is none, instead of whether we fall back to IOLoop.instance() (which is now an alias for this method). instance=False is deprecated, since even if we do not create an IOLoop, this method may initialize the asyncio loop.

IOLoop.make_current()[源代码]

Makes this the IOLoop for the current thread.

An IOLoop automatically becomes current for its thread when it is started, but it is sometimes useful to call make_current explicitly before starting the IOLoop, so that code run at startup time can find the right instance.

在 4.1 版更改: An IOLoop created while there is no current IOLoop will automatically become current.

在 5.0 版更改: This method also sets the current asyncio event loop.

static IOLoop.clear_current()[源代码]

Clears the IOLoop for the current thread.

Intended primarily for use by test frameworks in between tests.

在 5.0 版更改: This method also clears the current asyncio event 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 stop has been called, the IOLoop is not completely stopped until IOLoop.start has also returned. Some work that was scheduled before the call to stop may still be run before the IOLoop shuts 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, the IOLoop will run until the awaitable is resolved (and run_sync() will return the awaitable’s result). If it raises an exception, the IOLoop will stop and the exception will be re-raised to the caller.

The keyword-only argument timeout may be used to set a maximum duration for the function. If the timeout expires, a tornado.util.TimeoutError is 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 func coroutine will be cancelled.

IOLoop.close(all_fds=False)[源代码]

Closes the IOLoop, freeing any resources used.

If all_fds is true, all file descriptors registered on the IOLoop will be closed (not just the ones created by the IOLoop itself).

Many applications will only use a single IOLoop that runs for the entire lifetime of the process. In that case closing the IOLoop is not necessary since everything will be cleaned up when the process exits. IOLoop.close is provided mainly for scenarios such as unit tests, which create and destroy a large number of IOLoops.

An IOLoop must be completely stopped before it can be closed. This means that IOLoop.stop() must be called and IOLoop.start() must be allowed to return before attempting to call IOLoop.close(). Therefore the call to close will usually appear just after the call to start rather than near the call to stop.

在 3.1 版更改: If the IOLoop implementation supports non-integer objects for “file descriptors”, those objects will have their close method when all_fds is true.

static IOLoop.instance()[源代码]

Deprecated alias for IOLoop.current().

在 5.0 版更改: Previously, this method returned a global singleton IOLoop, in contrast with the per-thread IOLoop returned by current(). 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’s IOLoop). This distinction is not present in asyncio, so in order to facilitate integration with that package instance() was changed to be an alias to current(). Applications using the cross-thread communications aspect of instance() should instead set their own global variable to point to the IOLoop they want to use.

5.0 版后已移除.

IOLoop.install()[源代码]

Deprecated alias for make_current().

在 5.0 版更改: Previously, this method would set this IOLoop as the global singleton used by IOLoop.instance(). Now that instance() is an alias for current(), install() is an alias for make_current().

5.0 版后已移除.

static IOLoop.clear_instance()[源代码]

Deprecated alias for clear_current().

在 5.0 版更改: Previously, this method would clear the IOLoop used as the global singleton by IOLoop.instance(). Now that instance() is an alias for current(), clear_instance() is an alias for clear_current().

5.0 版后已移除.

I/O events

IOLoop.add_handler(fd, handler, events)[源代码]

Registers the given handler to receive the given events for fd.

The fd argument may either be an integer file descriptor or a file-like object with a fileno() method (and optionally a close() method, which may be called when the IOLoop is shut down).

The events argument is a bitwise or of the constants IOLoop.READ, IOLoop.WRITE, and IOLoop.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.

IOLoop.update_handler(fd, events)[源代码]

Changes the events we listen for fd.

在 4.0 版更改: Added the ability to pass file-like objects in addition to raw file descriptors.

IOLoop.remove_handler(fd)[源代码]

Stop listening for events on fd.

在 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 IOLoop that makes this thread-safety guarantee; all other interaction with the IOLoop must be done from that IOLoop’s thread. add_callback() may be used to transfer control from other threads to the IOLoop’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 IOLoop when the given Future is finished.

The callback is invoked with one argument, the Future.

This method only accepts Future objects and not other awaitables (unlike most of Tornado where the two are interchangeable).

IOLoop.add_timeout(deadline, callback, *args, **kwargs)[源代码]

Runs the callback at the time deadline from the I/O loop.

Returns an opaque handle that may be passed to remove_timeout to cancel.

deadline may be a number denoting a time (on the same scale as IOLoop.time, normally time.time), or a datetime.timedelta object for a deadline relative to the current time. Since Tornado 4.0, call_later is 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_timeout from other threads. Instead, you must use add_callback to transfer control to the IOLoop’s thread, and then call add_timeout from there.

Subclasses of IOLoop must implement either add_timeout or call_at; the default implementations of each will call the other. call_at is usually easier to implement, but subclasses that wish to maintain compatibility with Tornado versions prior to 4.0 must use add_timeout instead.

在 4.0 版更改: Now passes through *args and **kwargs to the callback.

IOLoop.call_at(when, callback, *args, **kwargs)[源代码]

Runs the callback at the absolute time designated by when.

when must be a number using the same reference point as IOLoop.time.

Returns an opaque handle that may be passed to remove_timeout to cancel. Note that unlike the asyncio method of the same name, the returned object does not have a cancel() method.

See add_timeout for comments on thread-safety and subclassing.

4.0 新版功能.

IOLoop.call_later(delay, callback, *args, **kwargs)[源代码]

Runs the callback after delay seconds have passed.

Returns an opaque handle that may be passed to remove_timeout to cancel. Note that unlike the asyncio method of the same name, the returned object does not have a cancel() method.

See add_timeout for 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 call remove_timeout even 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_callback does not associate the callback with its caller’s stack_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. If executor is None, the IO loop’s default executor will be used.

Use functools.partial to pass keyword arguments to func.

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 is time.time. However, it may be configured to use e.g. time.monotonic instead. Calls to add_timeout that pass a number instead of a datetime.timedelta should 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_time milliseconds. Note that the timeout is given in milliseconds, while most other time-related functions in Tornado use seconds.

If jitter is specified, each callback time will be randomly selected within a window of jitter * callback_time milliseconds. 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 on callback_time so 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_time milliseconds, subsequent invocations will be skipped to get back on schedule.

start must be called after the PeriodicCallback is created.

在 5.0 版更改: The io_loop argument (deprecated since version 4.1) has been removed.

在 5.1 版更改: The jitter argument is added.

start()[源代码]

Starts the timer.

stop()[源代码]

Stops the timer.

is_running()[源代码]

Return True if this PeriodicCallback has been started.

4.1 新版功能.

Debugging and error handling

IOLoop.handle_callback_exception(callback)[源代码]

This method is called whenever a callback run by the IOLoop throws 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.

在 5.0 版更改: When the asyncio event loop is used (which is now the default on Python 3), some callback errors will be handled by asyncio instead of this method.

IOLoop.set_blocking_signal_threshold(seconds, action)[源代码]

Sends a signal if the IOLoop is blocked for more than s seconds.

Pass seconds=None to disable. Requires Python 2.6 on a unixy platform.

The action parameter is a Python signal handler. Read the documentation for the signal module for more information. If action is None, the process will be killed if it is blocked for too long.

5.0 版后已移除: Not implemented on the asyncio event loop. Use the environment variable PYTHONASYNCIODEBUG=1 instead. This method will be removed in Tornado 6.0.

IOLoop.set_blocking_log_threshold(seconds)[源代码]

Logs a stack trace if the IOLoop is blocked for more than s seconds.

Equivalent to set_blocking_signal_threshold(seconds, self.log_stack)

5.0 版后已移除: Not implemented on the asyncio event loop. Use the environment variable PYTHONASYNCIODEBUG=1 instead. 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.initialize(make_current=None)[源代码]
IOLoop.close_fd(fd)[源代码]

Utility method to close an fd.

If fd is a file-like object, we close it directly; otherwise we use os.close.

This method is provided for use by IOLoop subclasses (in implementations of IOLoop.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 fd parameter.

We accept both raw file descriptors and file-like objects as input to add_handler and related methods. When a file-like object is passed, we must retain the object itself so we can close it correctly when the IOLoop shuts down, but the poller interfaces favor file descriptors (they will accept file-like objects and call fileno() for you, but they always return the descriptor itself).

This method is provided for use by IOLoop subclasses and should not generally be used by application code.

4.0 新版功能.