class_docstr: Same as :class:`MapData`, but start processes to run the mapping function,
  and communicate with ZeroMQ pipe.
  
  The semantics of this class is **identical** to :class:`MapData` except for the ordering.
  Processes run in parallel and can take different time to run the
  mapping function. Therefore the order of datapoints won't be preserved.
  
  When ``strict=True``, ``MultiProcessMapData(df, ...)``
  is guaranteed to produce the exact set of data as ``MapData(df, ...)``,
  if both are iterated until ``StopIteration``. But the produced data will have different ordering.
  The behavior of strict mode is undefined if the given dataflow ``df`` is infinite.
  
  When ``strict=False``, the data that's produced by ``MultiProcessMapData(df, ...)``
  is a reordering of the data produced by ``RepeatedData(MapData(df, ...), -1)``.
  In other words, first pass of ``MultiProcessMapData.__iter__`` may contain
  datapoints from the second pass of ``df.__iter__``.
docstr: Args:
      ds (DataFlow): the dataflow to map
      num_proc(int): number of threads to use
      map_func (callable): datapoint -> datapoint | None. Return None to
          discard/skip the datapoint.
      buffer_size (int): number of datapoints in the buffer
      strict (bool): use "strict mode", see notes above.
docstr_tok: ["Args",":","ds","(","DataFlow",")",":","the","dataflow","to","map","num_proc","(","int",")",":","number","of","threads","to","use","map_func","(","callable",")",":","datapoint","-",">","datapoint","|","None",".","Return","None","to","discard\/skip","the","datapoint",".","buffer_size","(","int",")",":","number","of","datapoints","in","the","buffer","strict","(","bool",")",":","use","``","strict","mode","''",",","see","notes","above","."]
code: def __init__(
      self,
      ds,
      num_proc=None,
      map_func=None,
      *,
      buffer_size=200,
      strict=False,
  ):
      """
      Args:
          ds (DataFlow): the dataflow to map
          num_proc(int): number of threads to use
          map_func (callable): datapoint -> datapoint | None. Return None to
              discard/skip the datapoint.
          buffer_size (int): number of datapoints in the buffer
          strict (bool): use "strict mode", see notes above.
      """
      if strict:
          # In strict mode, buffer size cannot be larger than the total number of datapoints
          try:
              buffer_size = min(buffer_size, len(ds))
          except Exception:  # ds may not have a length
              pass
  
      _ParallelMapData.__init__(self, ds, buffer_size, strict)
      _MultiProcessZMQDataFlow.__init__(self)
      assert num_proc > 0, num_proc
      self.num_proc = num_proc
      self.map_func = map_func
      self._strict = strict
      self._procs = []
  
imports: import copy
  import ctypes
  import multiprocessing
  import numpy
  import threading
  import zmq
  from six.moves import queue
  from ..utils.concurrency import StoppableThread, enable_death_signal
  from ..utils.serialize import dumps_once, loads_once
  from .base import DataFlow, DataFlowReentrantGuard, ProxyDataFlow
  from .common import RepeatedData, BatchData
  from .parallel import _bind_guard, _get_pipe_name, _MultiProcessZMQDataFlow, _repeat_iter, _zmq_catch_error
label_desc: Use image node_id 1 to create a new MultiProcessMapDataZMQ object from inherited base classes: _ParallelMapData, _MultiProcessZMQDataFlow with example: obj = MultiProcessMapDataZMQ(ds, num_proc, map_func)