def __init__(self, env_fns, spaces=None, context='<STR_LIT>'):
self.waiting = False<EOL>self.closed = False<EOL>nenvs = len(env_fns)<EOL>ctx = mp.get_context(context)<EOL>self.remotes, self.work_remotes = zip(*[ctx.Pipe() for _ in range(nenvs)])<EOL>self.ps = [ctx.Process(target=worker, args=(work_remote, remote, CloudpickleWrapper(env_fn)))<EOL>for (work_remote, remote, env_fn) in zip(self.work_remotes, self.remotes, env_fns)]<EOL>for p in self.ps:<EOL><INDENT>p.daemon = True  <EOL>with clear_mpi_env_vars():<EOL><INDENT>p.start()<EOL><DEDENT><DEDENT>for remote in self.work_remotes:<EOL><INDENT>remote.close()<EOL><DEDENT>self.remotes[<NUM_LIT:0>].send(('<STR_LIT>', None))<EOL>observation_space, action_space, self.spec = self.remotes[<NUM_LIT:0>].recv()<EOL>self.viewer = None<EOL>VecEnv.__init__(self, len(env_fns), observation_space, action_space)<EOL>
Arguments:

env_fns: iterable of callables -  functions that create environments to run in subprocesses. Need to be cloud-pickleable