docs: def start_workers(self, number: int=DEFAULT_WORKER_NUMBER,
                        queue=DEFAULT_QUEUE, block=True,
                        stop_when_queue_empty=False):
          """Start the worker threads.
  
          :arg number: number of worker threads to launch
          :arg queue: name of the queue to consume, see :doc:`queues`
          :arg block: whether to block the calling thread until a signal arrives
               and workers get terminated
          :arg stop_when_queue_empty: automatically stop the workers when the
               queue is empty. Useful mostly for one-off scripts and testing.
          """
          if self._arbiter or self._workers:
              raise RuntimeError('Workers are already running')
  
          self._working_queue = queue
  
          tasks_names = '\n'.join(
              ['  - ' + task.name for task in self._tasks.tasks.values()
               if task.queue == self._working_queue]
          )
          logger.info('Starting %d workers on queue "%s" with tasks:\n%s',
                      number, self._working_queue, tasks_names)
  
          # Start the broker
          self._broker.start()
  
          # Start workers
          self._workers = Workers(
              num_workers=number,
              namespace=self.namespace,
          )
  
          # Start the result notifier
          self._result_notifier = threading.Thread(
              target=run_forever,
              args=(self._result_notifier_func, self._must_stop, logger),
              name='{}-result-notifier'.format(self.namespace)
          )
          self._result_notifier.start()
  
          # Start the arbiter
          self._arbiter = threading.Thread(
              target=run_forever,
              args=(self._arbiter_func, self._must_stop, logger,
                    stop_when_queue_empty),
              name='{}-arbiter'.format(self.namespace)
          )
          self._arbiter.start()
  
          if block:
              with handle_sigterm():
                  try:
                      self._arbiter.join()
                  except KeyboardInterrupt:
                      self.stop_workers()
                  except AttributeError:
                      # Arbiter thread starts and stops immediately when ran with
                      # `stop_when_queue_empty` and queue is already empty.
                      pass