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 debug=True option to tornado.web.Application).
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.