(root)/
Python-3.11.7/
Lib/
multiprocessing/
popen_spawn_posix.py
       1  import io
       2  import os
       3  
       4  from .context import reduction, set_spawning_popen
       5  from . import popen_fork
       6  from . import spawn
       7  from . import util
       8  
       9  __all__ = ['Popen']
      10  
      11  
      12  #
      13  # Wrapper for an fd used while launching a process
      14  #
      15  
      16  class ESC[4;38;5;81m_DupFd(ESC[4;38;5;149mobject):
      17      def __init__(self, fd):
      18          self.fd = fd
      19      def detach(self):
      20          return self.fd
      21  
      22  #
      23  # Start child process using a fresh interpreter
      24  #
      25  
      26  class ESC[4;38;5;81mPopen(ESC[4;38;5;149mpopen_forkESC[4;38;5;149m.ESC[4;38;5;149mPopen):
      27      method = 'spawn'
      28      DupFd = _DupFd
      29  
      30      def __init__(self, process_obj):
      31          self._fds = []
      32          super().__init__(process_obj)
      33  
      34      def duplicate_for_child(self, fd):
      35          self._fds.append(fd)
      36          return fd
      37  
      38      def _launch(self, process_obj):
      39          from . import resource_tracker
      40          tracker_fd = resource_tracker.getfd()
      41          self._fds.append(tracker_fd)
      42          prep_data = spawn.get_preparation_data(process_obj._name)
      43          fp = io.BytesIO()
      44          set_spawning_popen(self)
      45          try:
      46              reduction.dump(prep_data, fp)
      47              reduction.dump(process_obj, fp)
      48          finally:
      49              set_spawning_popen(None)
      50  
      51          parent_r = child_w = child_r = parent_w = None
      52          try:
      53              parent_r, child_w = os.pipe()
      54              child_r, parent_w = os.pipe()
      55              cmd = spawn.get_command_line(tracker_fd=tracker_fd,
      56                                           pipe_handle=child_r)
      57              self._fds.extend([child_r, child_w])
      58              self.pid = util.spawnv_passfds(spawn.get_executable(),
      59                                             cmd, self._fds)
      60              self.sentinel = parent_r
      61              with open(parent_w, 'wb', closefd=False) as f:
      62                  f.write(fp.getbuffer())
      63          finally:
      64              fds_to_close = []
      65              for fd in (parent_r, parent_w):
      66                  if fd is not None:
      67                      fds_to_close.append(fd)
      68              self.finalizer = util.Finalize(self, util.close_fds, fds_to_close)
      69  
      70              for fd in (child_r, child_w):
      71                  if fd is not None:
      72                      os.close(fd)