docstr: envs: list of gym environments to run in subprocesses
docstr_tok: ["envs",":","list","of","gym","environments","to","run","in","subprocesses"]
code: def __init__(self, env_fns, spaces=None):
      """
      envs: list of gym environments to run in subprocesses
      """
      self.waiting = False
      self.closed = False
      nenvs = len(env_fns)
      self.remotes, self.work_remotes = zip(
          *[Pipe() for _ in range(nenvs)]
      )
      self.ps = [
          Process(
              target=worker,
              args=(work_remote, remote, CloudpickleWrapper(env_fn)),
          )
          for (work_remote, remote, env_fn) in zip(
              self.work_remotes, self.remotes, env_fns
          )
      ]
      for p in self.ps:
          p.daemon = True  # if the main process crashes, we should not cause things to hang
          p.start()
      for remote in self.work_remotes:
          remote.close()
  
      self.remotes[0].send(("get_spaces", None))
      observation_space, action_space = self.remotes[0].recv()
      VecEnv.__init__(
          self, len(env_fns), observation_space, action_space
      )
  
file_path: keras-rl/rl/common/vec_env/subproc_env_vec.py
imports: import numpy
  from multiprocessing import Process, Pipe
  from rl.common.vec_env import VecEnv, CloudpickleWrapper
  from rl.common.tile_images import tile_images
label_desc: Use image node_id 1 to create a new SubprocVecEnv object from inherited base classes: VecEnv with example: obj = SubprocVecEnv(env_fns, spaces)