docs: def start(self, as_thread=True, daemon=False, __state_check=True):
      """
      Starts the job. If the job was run once before, resets it completely. Can
      not be used while the job is running (raises #InvalidState).
  
      # Arguments
      as_thread (bool): Start the job in a separate thread. This is #True by
        default. Classes like the #ThreadPool calls this function from its own
        thread and passes #False for this argument.
      daemon (bool): If a thread is created with *as_thread* set to #True,
        defines whether the thread is started as a daemon or not. Defaults to
        #False.
  
      # Returns
      Job: The job object itself.
      """
  
      if __state_check:
        # We need to manually manage the lock to be able to release it
        # pre-emptively when needed.
        with synchronized(self):
          if self.__cancelled and self.__state == Job.PENDING:
            # Cancelled in PENDING state. Do not run the target function at all.
            self.__state = Job.CANCELLED
            assert self.__exception is None
            assert self.__result is None
            self._trigger_event(Job.CANCELLED)
            return None
  
          if self.__state == Job.RUNNING:
            raise Job.InvalidState('job is already running')
          elif self.__state not in (Job.PENDING, Job.ERROR, Job.SUCCESS, Job.CANCELLED):
            raise RuntimeError('invalid job state {0!r}'.format(self.__state))
  
          # Reset the Job attributes.
          self.__state = Job.RUNNING
          self.__cancelled = False
          self.__result = None
          self.__exception = None
          self.__event_set.clear()
          self.__thread = None
  
          # Remove all listeners that have been registered with the "once" flag.
          for listeners in self.__listeners.values():
            listeners[:] = (l for l in listeners if not l.once)
  
      if as_thread:
        thread = threading.Thread(target=self.start, args=(False, False, False))
        thread.setDaemon(daemon)
        with synchronized(self):
          assert not self.__thread or not self.__thread.running
          self.__thread = thread
        thread.start()
        return self
  
      try:
        result = None
        exception = None
        try:
          result = self.run()
          state = Job.SUCCESS
        except Exception:  # XXX: Catch BaseException?
          if self.print_exc:
            traceback.print_exc()
          exception = Job.ExceptionInfo(*sys.exc_info())
          state = Job.ERROR
  
        with synchronized(self):
          cancelled = self.__cancelled
          self.__result = result
          self.__exception = exception
          self.__state = Job.CANCELLED if cancelled else state
  
        self._trigger_event(state)
      finally:
        with synchronized(self):
          notify_all(self)
        if self.__dispose_inputs:
          self.__target = None
          self.__args = None
          self.__kwargs = None
          self.data = None
          for listeners in self.__listeners.values():
            listeners[:] = []
  
      return self