tornado.process — Utilities for multiple processes

Utilities for working with multiple processes, including both forking the server into multiple processes and managing subprocesses.

exception tornado.process.CalledProcessError[source]

An alias for subprocess.CalledProcessError.

exception tornado.process.CalledProcessError(returncode, cmd, output=None, stderr=None)[source]

Raised when run() is called with check=True and the process returns a non-zero exit status.


cmd, returncode, stdout, stderr, output

property stdout

Alias for output attribute, to match stderr

tornado.process.cpu_count() → int[source]

Returns the number of processors on this machine.

tornado.process.fork_processes(num_processes: Optional[int], max_restarts: int = None) → int[source]

Starts multiple worker processes.

If num_processes is None or <= 0, we detect the number of cores available on this machine and fork that number of child processes. If num_processes is given and > 0, we fork that specific number of sub-processes.

Since we use processes and not threads, there is no shared memory between any server code.

Note that multiple processes are not compatible with the autoreload module (or the autoreload=True option to tornado.web.Application which defaults to True when debug=True). When using multiple processes, no IOLoops can be created or referenced until after the call to fork_processes.

In each child process, fork_processes returns its task id, a number between 0 and num_processes. Processes that exit abnormally (due to a signal or non-zero exit status) are restarted with the same id (up to max_restarts times). In the parent process, fork_processes returns None if all child processes have exited normally, but will otherwise only exit by throwing an exception.

max_restarts defaults to 100.

tornado.process.task_id() → Optional[int][source]

Returns the current task id, if any.

Returns None if this process was not created by fork_processes.

class tornado.process.Subprocess(*args, **kwargs)[source]

Wraps subprocess.Popen with IOStream support.

The constructor is the same as subprocess.Popen with the following additions:

  • stdin, stdout, and stderr may have the value tornado.process.Subprocess.STREAM, which will make the corresponding attribute of the resulting Subprocess a PipeIOStream. If this option is used, the caller is responsible for closing the streams when done with them.

The Subprocess.STREAM option and the set_exit_callback and wait_for_exit methods do not work on Windows. There is therefore no reason to use this class instead of subprocess.Popen on that platform.

Changed in version 5.0: The io_loop argument (deprecated since version 4.1) has been removed.

set_exit_callback(callback: Callable[[int], None]) → None[source]

Runs callback when this process exits.

The callback takes one argument, the return code of the process.

This method uses a SIGCHLD handler, which is a global setting and may conflict if you have other libraries trying to handle the same signal. If you are using more than one IOLoop it may be necessary to call Subprocess.initialize first to designate one IOLoop to run the signal handlers.

In many cases a close callback on the stdout or stderr streams can be used as an alternative to an exit callback if the signal handler is causing a problem.

wait_for_exit(raise_error: bool = True) → Future[int][source]

Returns a Future which resolves when the process exits.


ret = yield proc.wait_for_exit()

This is a coroutine-friendly alternative to set_exit_callback (and a replacement for the blocking subprocess.Popen.wait).

By default, raises subprocess.CalledProcessError if the process has a non-zero exit status. Use wait_for_exit(raise_error=False) to suppress this behavior and return the exit status without raising.

New in version 4.2.

classmethod initialize() → None[source]

Initializes the SIGCHLD handler.

The signal handler is run on an IOLoop to avoid locking issues. Note that the IOLoop used for signal handling need not be the same one used by individual Subprocess objects (as long as the IOLoops are each running in separate threads).


classmethod uninitialize() → None[source]

Removes the SIGCHLD handler.