def __init__(self, env_fns, spaces=None):
self.waiting = False<EOL>self.closed = False<EOL>nenvs = len(env_fns)<EOL>self.remotes, self.work_remotes = zip(*[Pipe() for _ in range(nenvs)])<EOL>self.ps = [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>p.start()<EOL><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.remotes[<NUM_LIT:0>].recv()<EOL>VecEnv.__init__(self, len(env_fns), observation_space, action_space)<EOL>
envs: list of gym environments to run in subprocesses