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.
docstr: Collect at least a given number transitions (timesteps).
  
  Args:
      itr(int): The current iteration number. Using this argument is
          deprecated.
      num_samples (int): Minimum number of transitions / timesteps to
          sample.
      agent_update (object): Value which will be passed into the
          `agent_update_fn` before sampling episodes. If a list is passed
          in, it must have length exactly `factory.n_workers`, and will
          be spread across the workers.
      env_update (object): Value which will be passed into the
          `env_update_fn` before sampling episodes. If a list is passed
          in, it must have length exactly `factory.n_workers`, and will
          be spread across the workers.
  
  Returns:
      EpisodeBatch: The batch of collected episodes.
  
  Raises:
      AssertionError: On internal errors.
docstr_tok: ["Collect","at","least","a","given","number","transitions","(","timesteps",")",".","Args",":","itr","(","int",")",":","The","current","iteration","number",".","Using","this","argument","is","deprecated",".","num_samples","(","int",")",":","Minimum","number","of","transitions","\/","timesteps","to","sample",".","agent_update","(","object",")",":","Value","which","will","be","passed","into","the","`","agent_update_fn","`","before","sampling","episodes",".","If","a","list","is","passed","in",",","it","must","have","length","exactly","`","factory.n_workers","`",",","and","will","be","spread","across","the","workers",".","env_update","(","object",")",":","Value","which","will","be","passed","into","the","`","env_update_fn","`","before","sampling","episodes",".","If","a","list","is","passed","in",",","it","must","have","length","exactly","`","factory.n_workers","`",",","and","will","be","spread","across","the","workers",".","Returns",":","EpisodeBatch",":","The","batch","of","collected","episodes",".","Raises",":","AssertionError",":","On","internal","errors","."]
code: def obtain_samples(
      self, itr, num_samples, agent_update, env_update=None
  ):
      """Collect at least a given number transitions (timesteps).
  
      Args:
          itr(int): The current iteration number. Using this argument is
              deprecated.
          num_samples (int): Minimum number of transitions / timesteps to
              sample.
          agent_update (object): Value which will be passed into the
              `agent_update_fn` before sampling episodes. If a list is passed
              in, it must have length exactly `factory.n_workers`, and will
              be spread across the workers.
          env_update (object): Value which will be passed into the
              `env_update_fn` before sampling episodes. If a list is passed
              in, it must have length exactly `factory.n_workers`, and will
              be spread across the workers.
  
      Returns:
          EpisodeBatch: The batch of collected episodes.
  
      Raises:
          AssertionError: On internal errors.
  
      """
      del itr
      batches = []
      completed_samples = 0
      self._agent_version += 1
      updated_workers = set()
      agent_ups = self._factory.prepare_worker_messages(
          agent_update, cloudpickle.dumps
      )
      env_ups = self._factory.prepare_worker_messages(
          env_update, cloudpickle.dumps
      )
  
      with click.progressbar(
          length=num_samples, label="Sampling"
      ) as pbar:
          while completed_samples < num_samples:
              self._push_updates(updated_workers, agent_ups, env_ups)
              for _ in range(self._factory.n_workers):
                  try:
                      tag, contents = self._to_sampler.get_nowait()
                      if tag == "episode":
                          batch, version, worker_n = contents
                          del worker_n
                          if version == self._agent_version:
                              batches.append(batch)
                              num_returned_samples = batch.lengths.sum()
                              completed_samples += num_returned_samples
                              pbar.update(num_returned_samples)
                          else:
                              # Receiving episodes from previous iterations
                              # is normal.  Potentially, we could gather them
                              # here, if an off-policy method wants them.
                              pass
                      else:
                          raise AssertionError(
                              "Unknown tag {} with contents {}".format(
                                  tag, contents
                              )
                          )
                  except queue.Empty:
                      pass
          for q in self._to_worker:
              try:
                  q.put_nowait(("stop", ()))
              except queue.Full:
                  pass
  
      samples = EpisodeBatch.concatenate(*batches)
      self.total_env_steps += sum(samples.lengths)
      return samples
  
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 4 for calling the MultiprocessingSampler obj's underlying member method code with example usage: obj.obtain_samples(itr, num_samples, agent_update, env_update) and returns: samples