K i1>dZddlZddlZddlZddlZddlZddlZddlZddlm Z ddl m Z m Z m Z ddlmZddlmZddlmZddlZddlmZmZmZej0rdd lmZej4Zd efd Zdd Zda dd eedeed efdZd eefdZ GddZ!y)zUtilities for working with multiple processes, including both forking the server into multiple processes and managing subprocesses. N)hexlify)Future"future_set_result_unless_cancelled%future_set_exception_unless_cancelled)ioloop) PipeIOStream)gen_log)OptionalAnyCallable)Listreturncty tjS#t$rYnwxYw tjdS#t t f$rYnwxYwtjdy)z1Returns the number of processors on this machine.SC_NPROCESSORS_CONFz1Could not detect number of processors; assuming 1) multiprocessing cpu_countNotImplementedErrorossysconfAttributeError ValueErrorr errorU/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/tornado/process.pyrr1sm ((**     zz/00 J '    MMEF s ))AAAc.dtjvryddl} tt t j dd}|j|y#t$r8ttjdzt jz }YRwxYw)Nrandomri) sysmodulesrintrrurandomrtimegetpidseed)rr&s r_reseed_randomr'Asqs{{" 572::b>*B/ KK 5499;%&45s(A>BB num_processes max_restartsc( tjdk(r td|d}tJ||dkr t }t j d|i dtdttf fd }t|D]}||}||cSd} rtj\}}| vr j|}tj|r,t jd ||tj|n\tj |dk7r,t jd ||tj |nt j d |||d z }||kDr t#d||}||S rtj$dy)aqStarts 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`` calls ``sys.exit(0)`` after all child processes have exited normally. max_restarts defaults to 100. Availability: Unix win32zfork not available on windowsNdrzStarting %d processesirc^tj}|dk(rt|a|S||<yNr)rforkr'_task_id)r-pidchildrens r start_childz#fork_processes..start_childs1ggi !8  HHHSMrz1child %d (pid %d) killed by signal %d, restartingz3child %d (pid %d) exited with status %d, restartingz!child %d (pid %d) exited normallyrz"Too many child restarts, giving up)r platform Exceptionr1rr infor"r rangerwaitpop WIFSIGNALEDwarningWTERMSIG WEXITSTATUS RuntimeErrorexit) r(r)r4r-id num_restartsr2statusnew_idr3s @rfork_processesrESs< ||w788      2!  LL(-8H s x} = ! ^ >IL ggi V h   \\#  >>& ! OOC F#   ^^F #q ( OOEv&   LLD4&dGDIIt$<= >#     s <HH0callbackc||_tj|tj|j<tj |jy)aRuns ``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. Availability: Unix N)r_rI initialize_waitingr2_try_cleanup_process)rarms rset_exit_callbackzSubprocess.set_exit_callbacks>"'(, DHH%''1r raise_errorz Future[int]c^tdtddffd }|j|S)a2Returns a `.Future` which resolves when the process exits. Usage:: 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. .. versionadded:: 4.2 Availability: Unix retrNcZ|dk7rrtt|dyt|y)Nrunknown)rCalledProcessErrorr)rufuturerss rrmz*Subprocess.wait_for_exit..callback(s-axK5.sI>363?r)rr"rr)rarsrmrys ` @r wait_for_exitzSubprocess.wait_for_exits7$ @# @$ @ x( rc|jrytj}|jtj |j d|_y)aInitializes 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). .. versionchanged:: 5.0 The ``io_loop`` argument (deprecated since version 4.1) has been removed. Availability: Unix NT) _initializedasyncioget_event_loopadd_signal_handlersignalSIGCHLD_cleanupclsloops rrozSubprocess.initialize4s>    %%'  =rc|jsytj}|jtj d|_y)z Removes the ``SIGCHLD`` handler.NF)r|r}r~remove_signal_handlerrrrs r uninitializezSubprocess.uninitializeIs8 %%' ""6>>2 rcvt|jjD]}|j|yN)listrpkeysrq)rr2s rrzSubprocess._cleanupRs1 ))+, *C  $ $S ) *rr2c tj|tj\}}|dk(ry||k(sJ|jj |}|j j|j|y#t$rYywxYwr/) rwaitpidWNOHANGChildProcessErrorrpr:rR add_callback_set_returncode)rr2ret_pidrCsubprocs rrqzSubprocess._try_cleanup_processWsy  jjbjj9OGV a< #~~,,""3'$$W%<%rZr_)rarCrms rrzSubprocess._set_returncodecs <<7 " DO~~f%#%;;v#6"6||F+++"$.."8 $    **H"&D  T__ % r)TrN)__name__ __module__ __qualname____doc__objectrTr|rpr rlr r"rrboolrz classmethodrorrrqrrrrrIrIs*XFLH%c%S%T%N2(C5$;*?2D2,@  (!!** Fs Ft F F&c&d&rrIrr)"rr}rrrrXr r$binasciirtornado.concurrentrrrtornadortornado.iostreamr tornado.logr typingr r r TYPE_CHECKINGr rxr"rr'r1rErGrIrrrrs     ) **  22  3   AE]C=]08 ]]@#w&w&r