          self.pool.close()
          self.pool.join()
  
  
  class SpawnProcess():
      """ Process in spawnable context
          Must be spawnable to share CUDA across processes """
      def __init__(self):
          self.context = mp.get_context("spawn")
          self.daemonize = True
 
</s> remove     def __init__(self):
        self.context = mp.get_context("spawn")
        self.daemonize = True
        self.process = None
        self.event = self.context.Event()

    def in_process(self, target, *args, **kwargs):
        """ Start a process in the spawn context """
 </s> add     def __init__(self, target, in_queue, out_queue, *args, **kwargs):
        name = target.__qualname__
        logger.debug("Initializing %s: (target: '%s', args: %s, kwargs: %s)",
                     self.__class__.__name__, name, args, kwargs)
        ctx = mp.get_context("spawn")
        self.event = ctx.Event()
        kwargs = self.build_target_kwargs(in_queue, out_queue, kwargs)
        super().__init__(target=target, name=name, args=args, kwargs=kwargs)
        self.daemon = True
        logger.debug("Initialized %s: '%s'", self.__class__.__name__, name)

    def build_target_kwargs(self, in_queue, out_queue, kwargs):
        """ Add standard kwargs to passed in kwargs list """ </s> remove     is_macos = False
 </s> add     IS_MACOS = False </s> remove         self.pool = None
 </s> add         ctx = mp.get_context("spawn")
        self.pool = ctx.Pool(processes=self.procs)

        self._method = method
        self._kwargs = self.build_target_kwargs(in_queue, out_queue, kwargs)
        self._args = args

        logger.debug("Initialized %s: '%s'", self.__class__.__name__, self._name)

    @staticmethod
    def build_target_kwargs(in_queue, out_queue, kwargs):
        """ Add standard kwargs to passed in kwargs list """
        kwargs["log_init"] = set_root_logger
        kwargs["log_queue"] = LOG_QUEUE
        kwargs["in_queue"] = in_queue
        kwargs["out_queue"] = out_queue
        return kwargs </s> remove         self.pool = mp.Pool(processes=self.procs)
        for _ in range(self.procs):
            self.pool.apply_async(self.method, args=args, kwds=kwargs)
 </s> add         logging.debug("Pooling Processes: (target: '%s', args: %s, kwargs: %s)",
                      self._name, self._args, self._kwargs)
        for idx in range(self.procs):
            logger.debug("Adding process %s of %s to mp.Pool '%s'",
                         idx + 1, self.procs, self._name)
            self.pool.apply_async(self._method, args=self._args, kwds=self._kwargs)
        logging.debug("Pooled Processes: '%s'", self._name)
class SpawnProcess(mp.context.SpawnProcess):
          self.pool.close()
          self.pool.join()
  
  
class SpawnProcess(mp.context.SpawnProcess):
      """ Process in spawnable context
          Must be spawnable to share CUDA across processes """
      def __init__(self):
          self.context = mp.get_context("spawn")
          self.daemonize = True
keep keep keep keep replace keep keep keep keep keep
 Logging (#541)

* Convert prints to logger. Further logging improvements. Tidy  up

* Fix system verbosity. Allow SystemExit

* Fix reload extract bug

* Child Traceback handling

* Safer shutdown procedure

* Add shutdown event to queue manager

* landmarks_as_xy > property. GUI notes + linting. Aligner bugfix

* fix FaceFilter. Enable nFilter when no Filter is supplied

* Fix blurry face filter

* Continue on IO error. Better error handling

* Explicitly print stack trace tocrash log

* Windows Multiprocessing bugfix

* Add git info and conda version to crash log

* Windows/Anaconda mp bugfix

* Logging fixes for training 
lib/multithreading.py