class_docstr: Sampler that uses multiprocessing to distribute workers.
  
  The sampler need to be created either from a worker factory or from
  parameters which can construct a worker factory. See the __init__ method
  of WorkerFactory for the detail of these parameters.
  
  Args:
      agents (Policy or List[Policy]): Agent(s) to use to sample episodes.
          If a list is passed in, it must have length exactly
          `worker_factory.n_workers`, and will be spread across the
          workers.
      envs (Environment or List[Environment]): Environment from which
          episodes are sampled. If a list is passed in, it must have length
          exactly `worker_factory.n_workers`, and will be spread across the
          workers.
      worker_factory (WorkerFactory): Pickleable factory for creating
          workers. Should be transmitted to other processes / nodes where
          work needs to be done, then workers should be constructed
          there. Either this param or params after this are required to
          construct a sampler.
      max_episode_length(int): Params used to construct a worker factory.
          The maximum length episodes which will be sampled.
      is_tf_worker (bool): Whether it is workers for TFTrainer.
      seed(int): The seed to use to initialize random number generators.
      n_workers(int): The number of workers to use.
      worker_class(type): Class of the workers. Instances should implement
          the Worker interface.
      worker_args (dict or None): Additional arguments that should be passed
          to the worker.
code: def __init__(
      self,
      agents,
      envs,
      *,  # After this require passing by keyword.
      worker_factory=None,
      max_episode_length=None,
      is_tf_worker=False,
      seed=get_seed(),
      n_workers=psutil.cpu_count(logical=False),
      worker_class=DefaultWorker,
      worker_args=None,
  ):
      # pylint: disable=super-init-not-called
      if worker_factory is None and max_episode_length is None:
          raise TypeError(
              "Must construct a sampler from WorkerFactory or"
              "parameters (at least max_episode_length)"
          )
      if isinstance(worker_factory, WorkerFactory):
          self._factory = worker_factory
      else:
          self._factory = WorkerFactory(
              max_episode_length=max_episode_length,
              is_tf_worker=is_tf_worker,
              seed=seed,
              n_workers=n_workers,
              worker_class=worker_class,
              worker_args=worker_args,
          )
  
      self._agents = self._factory.prepare_worker_messages(
          agents, cloudpickle.dumps
      )
      self._envs = self._factory.prepare_worker_messages(
          envs, cloudpickle.dumps
      )
      self._to_sampler = mp.Queue(2 * self._factory.n_workers)
      self._to_worker = [
          mp.Queue(1) for _ in range(self._factory.n_workers)
      ]
      # If we crash from an exception, with full queues, we would rather not
      # hang forever, so we would like the process to close without flushing
      # the queues.
      # That's what cancel_join_thread does.
      for q in self._to_worker:
          q.cancel_join_thread()
      self._workers = [
          mp.Process(
              target=run_worker,
              kwargs=dict(
                  factory=self._factory,
                  to_sampler=self._to_sampler,
                  to_worker=self._to_worker[worker_number],
                  worker_number=worker_number,
                  agent=self._agents[worker_number],
                  env=self._envs[worker_number],
              ),
              daemon=False,
          )
          for worker_number in range(self._factory.n_workers)
      ]
      self._agent_version = 0
      for w in self._workers:
          w.start()
      self.total_env_steps = 0
  
imports: from collections import defaultdict
  import itertools
  import multiprocessing
  import queue
  import click
  import cloudpickle
  import psutil
  import setproctitle
  from garage import EpisodeBatch
  from garage.experiment.deterministic import get_seed
  from garage.sampler.default_worker import DefaultWorker
  from garage.sampler.sampler import Sampler
  from garage.sampler.worker_factory import WorkerFactory
label_desc: Use image node_id 1 to create a new MultiprocessingSampler object from inherited base classes: Sampler with example: obj = MultiprocessingSampler(agents, envs)