class_docstr: A base thread to communicate with all SimulatorProcess.
  It should produce action for each simulator, as well as
  defining callbacks when a transition or an episode is finished.
class_docstr_tok: ["A","base","thread","to","communicate","with","all","SimulatorProcess",".","It","should","produce","action","for","each","simulator",",","as","well","as","defining","callbacks","when","a","transition","or","an","episode","is","finished","."]
docstr: Args:
      pipe_c2s, pipe_s2c (str): names of pipe to be used for communication
docstr_tok: ["Args",":","pipe_c2s",",","pipe_s2c","(","str",")",":","names","of","pipe","to","be","used","for","communication"]
code: def __init__(self, pipe_c2s, pipe_s2c):
      """
      Args:
          pipe_c2s, pipe_s2c (str): names of pipe to be used for communication
      """
      super(SimulatorMaster, self).__init__()
      assert os.name != "nt", "Doesn't support windows!"
      self.daemon = True
      self.name = "SimulatorMaster"
  
      self.context = zmq.Context()
  
      self.c2s_socket = self.context.socket(zmq.PULL)
      self.c2s_socket.bind(pipe_c2s)
      self.c2s_socket.set_hwm(10)
      self.s2c_socket = self.context.socket(zmq.ROUTER)
      self.s2c_socket.bind(pipe_s2c)
      self.s2c_socket.set_hwm(10)
  
      # queueing messages to client
      self.send_queue = queue.Queue(maxsize=100)
  
      def f():
          msg = self.send_queue.get()
          self.s2c_socket.send_multipart(msg, copy=False)
  
      self.send_thread = LoopThread(f)
      self.send_thread.daemon = True
      self.send_thread.start()
  
      # make sure socket get closed at the end
      def clean_context(soks, context):
          for s in soks:
              s.close()
          context.term()
  
      import atexit
  
      atexit.register(
          clean_context,
          [self.c2s_socket, self.s2c_socket],
          self.context,
      )
  
imports: import multiprocessing
  import os
  import threading
  import time
  from abc import ABCMeta, abstractmethod
  from collections import defaultdict
  import six
  import zmq
  from six.moves import queue
  from tensorpack.utils import logger
  from tensorpack.utils.concurrency import LoopThread, enable_death_signal, ensure_proc_terminate
  from tensorpack.utils.serialize import dumps, loads
label_desc: Use image node_id 1 to create a new SimulatorMaster object from inherited base classes: threading with example: obj = SimulatorMaster(pipe_c2s, pipe_s2c)