class_docstr: Similar to :class:`MapDataComponent`, but perform IPC by shared memory,
  therefore more efficient when data (result of map_func) is large.
  It requires `map_func` to always return a numpy array of fixed shape and dtype, or None.
docstr: Args:
      ds (DataFlow): the dataflow to map on
      nr_proc(int): number of processes
      map_func (data component -> ndarray | None): the mapping function
      output_shape (tuple): the shape of the output of map_func
      output_dtype (np.dtype): the type of the output of map_func
      index (int): the index of the datapoint component to map on.
docstr_tok: ["Args",":","ds","(","DataFlow",")",":","the","dataflow","to","map","on","nr_proc","(","int",")",":","number","of","processes","map_func","(","data","component","-",">","ndarray","|","None",")",":","the","mapping","function","output_shape","(","tuple",")",":","the","shape","of","the","output","of","map_func","output_dtype","(","np.dtype",")",":","the","type","of","the","output","of","map_func","index","(","int",")",":","the","index","of","the","datapoint","component","to","map","on","."]
code: def __init__(
      self, ds, nr_proc, map_func, output_shape, output_dtype, index=0
  ):
      """
      Args:
          ds (DataFlow): the dataflow to map on
          nr_proc(int): number of processes
          map_func (data component -> ndarray | None): the mapping function
          output_shape (tuple): the shape of the output of map_func
          output_dtype (np.dtype): the type of the output of map_func
          index (int): the index of the datapoint component to map on.
      """
      self.ds = ds
      self.nr_proc = nr_proc
      self.map_func = map_func
      self.output_shape = output_shape
      self.output_dtype = np.dtype(output_dtype).type
      self.index = index
  
      self._shared_mem = [
          self._create_shared_arr() for k in range(nr_proc)
      ]
      id_queue = mp.Queue()
      for k in range(nr_proc):
          id_queue.put(k)
  
      def _init_pool(arrs, queue, map_func):
          id = queue.get()
          global SHARED_ARR, WORKER_ID, MAP_FUNC
          SHARED_ARR = arrs[id]
          WORKER_ID = id
          MAP_FUNC = map_func
  
      self._pool = mp.pool.Pool(
          processes=nr_proc,
          initializer=_init_pool,
          initargs=(self._shared_mem, id_queue, map_func),
      )
  
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 MultiProcessMapDataComponentSharedArray object from inherited base classes: DataFlow with example: obj = MultiProcessMapDataComponentSharedArray(ds, nr_proc, map_func, output_shape, output_dtype, index)